diff options
author | PostgreSQL Daemon | 2004-01-19 20:07:14 +0000 |
---|---|---|
committer | PostgreSQL Daemon | 2004-01-19 20:07:14 +0000 |
commit | 2a9bf5b33d0b82e9f483f6a5ced9d71e1c009441 (patch) | |
tree | 8c0c38494985b8dbfd2311b5be51fa76a271ba17 | |
parent | 9bd681a5220186230e0ea0f718a71af7ebe4b560 (diff) |
JDBC is now on GBorg
147 files changed, 0 insertions, 33298 deletions
diff --git a/src/interfaces/jdbc/Makefile b/src/interfaces/jdbc/Makefile deleted file mode 100644 index 1a8ebc6de7c..00000000000 --- a/src/interfaces/jdbc/Makefile +++ /dev/null @@ -1,44 +0,0 @@ -#------------------------------------------------------------------------- -# -# Makefile for JDBC driver -# -# Copyright (c) 2001, PostgreSQL Global Development Group -# -# $PostgreSQL: pgsql/src/interfaces/jdbc/Makefile,v 1.39 2003/11/29 19:52:09 pgsql Exp $ -# -#------------------------------------------------------------------------- - -subdir = src/interfaces/jdbc -top_builddir = ../../.. -include $(top_builddir)/src/Makefile.global - -majorversion:= $(shell echo $(VERSION) | sed 's/^\([0-9][0-9]*\)\..*$$/\1/') -minorversion:= $(shell echo $(VERSION) | sed 's/^[0-9][0-9]*\.\([0-9][0-9]*\).*$$/\1/') - -build.properties: $(top_builddir)/src/Makefile.global - @echo "# This file was created by 'make build.properties'." > build.properties - @echo major=$(majorversion) >> build.properties - @echo minor=$(minorversion) >> build.properties - @echo fullversion=$(VERSION) >> build.properties - @echo def_pgport=$(DEF_PGPORT) >> build.properties - @echo enable_debug=$(enable_debug) >> build.properties - -all: build.properties - $(ANT) -buildfile $(srcdir)/build.xml all - -install: installdirs build.properties - $(ANT) -buildfile $(srcdir)/build.xml install \ - -Dinstall.directory=$(javadir) - -installdirs: - $(mkinstalldirs) $(javadir) - -uninstall: - $(ANT) -buildfile $(srcdir)/build.xml uninstall \ - -Dinstall.directory=$(javadir) - -clean distclean maintainer-clean: - $(ANT) -buildfile $(srcdir)/build.xml clean_all - -check: build.properties - $(ANT) -buildfile $(srcdir)/build.xml test diff --git a/src/interfaces/jdbc/README b/src/interfaces/jdbc/README deleted file mode 100644 index 0c8555165ac..00000000000 --- a/src/interfaces/jdbc/README +++ /dev/null @@ -1,226 +0,0 @@ -This is a simple readme describing how to compile and use the jdbc driver. - ---------------------------------------------------------------------------- - -This isn't a guide on how to use JDBC - for that refer to sun's web site: - - http://java.sun.com/ - -For problems with this driver, then refer to the postgres-jdbc email -list: - - http://www.postgresql.org/ - -The Driver's home page is: - - http://jdbc.postgresql.org/ - ---------------------------------------------------------------------------- - -COMPILING - -To compile you will need to have ANT installed. To obtain ant go to -http://jakarta.apache.org/ant/index.html and download the binary. Being pure -java it will run on virtually all java platforms. If you have any problems -please email the jdbc list. - -Once you have ANT, run the configure script in the top-level directory with -the --with-java option. Then proceed with 'make' and 'make install' as -usual. This will compile the correct driver for your JVM, and build a .jar -file (Java ARchive) called postgresql.jar. The file will be installed in -the directory PREFIX/share/java. - -That jar file will contain the driver for _your_ version of the JDK. - -If you would like to use ANT directly, first invoke 'make build.properties' -after running the configure script with the java option. This will create a -needed Java properties file from the configured information. - -REMEMBER: Once you have compiled the driver, it will work on ALL platforms -that support that version of the API. You don't need to build it for each -platform. - -Possible problems - -You may see a message similar to: - -postgresql/Driver.java:87: interface java.sql.Connection is an interface. It can't be instantiated. - return new Connection (host(), port(), props, database(), url, this); - -This is caused by not having the current directory in your CLASSPATH. Under -Linux/Solaris, unset the CLASSPATH environment variable, and rerun ant. - -If you are still having problems, prebuilt versions of the driver -are available at http://jdbc.postgresql.org/ - ---------------------------------------------------------------------------- - -INSTALLING THE DRIVER - -To install the driver, the .class files have to be in the classpath. - -ie: under LINUX/SOLARIS (the example here is my linux box): - - export CLASSPATH=.:/usr/local/pgsql/share/java/postgresql.jar - ---------------------------------------------------------------------------- - -USING THE DRIVER - -To use the driver, you must introduce it to JDBC. Again, there's two ways -of doing this: - -1: Hardcoded. - - This method hardcodes your driver into your application/applet. You - introduce the driver using the following snippet of code: - - try { - Class.forName("org.postgresql.Driver"); - } catch(Exception e) { - // your error handling code goes here - } - - Remember, this method restricts your code to just the postgresql database. - However, this is how most people load the driver. - -2: Parameters - - This method specifies the driver from the command line. When running the - application, you specify the driver using the option: - - -Djdbc.drivers=org.postgresql.Driver - - eg: This is an example of running one of my other projects with the driver: - - java -Djdbc.drivers=org.postgresql.Driver uk.org.retep.finder.Main - - note: This method only works with Applications (not for Applets). - However, the application is not tied to one driver, so if you needed - to switch databases (why I don't know ;-) ), you don't need to - recompile the application (as long as you havent hardcoded the url's). - ---------------------------------------------------------------------------- - -JDBC URL syntax - -The driver recognises JDBC URL's of the form: - - jdbc:postgresql:database - - jdbc:postgresql://host/database - - jdbc:postgresql://host:port/database - -Also, you can supply both username and passwords as arguments, by appending -them to the URL. eg: - - jdbc:postgresql:database?user=me - jdbc:postgresql:database?user=me&password=mypass - -Notes: - -1) If you are connecting to localhost or 127.0.0.1 you can leave it out of the - URL. ie: jdbc:postgresql://localhost/mydb can be replaced with - jdbc:postgresql:mydb - -2) The port defaults to 5432 if it's left out. - ---------------------------------------------------------------------------- - -That's the basics related to this driver. You'll need to read the JDBC Docs -on how to use it. However, there are some examples included in the example -directory. To build, type: make examples - -To run them, they follow the same syntax. For example, the basic example shows -how to insert data, and perform queries: - - java example.basic jdbc:postgresql:test user password - ---------------------------------------------------------------------------- - -POSTGRESQL SPECIFICS --------------------- - -Large Objects: - -A "feature" of PostgreSQL is that access to LargeObjects is only permitted -within a Transaction. Because of this, any use of LargeObjects (also known -as Blobs) requires that the Connection.setAutoCommit() method be called -disabling the autocommit feature. - -For example: - - Connection db; // open the connection here - db.setAutoCommit(false); // Turn off AutoCommit - - ------------------ - -Large Object API - -The first thing you need to do is to open the LargeObjectManager. This class -handles the opening of existing objects, and creating new ones. To do this, -you use the following line of code: - - LargeObjectManager lobj; - lobj = ((org.postgresql.Connection)db).getLargeObjectAPI(); - -where db is a reference to an open Connection object. - -Once that is done, you can use the API for the lifetime of that Connection. - -To create an object, you call the create() method. This takes an argument -with the file modes you intend to use. The following line is normally -sufficient: - - int oid = lobj.create(LargeObjectManager.READ|LargeObjectManager.WRITE); - -Here, lobj is the LargeObjectManager we have opened earlier, and oid is the -Large Object's oid in the database. - -To open an existing object, you use the open() method. This takes an oid, and -the file permissions. It then returns a LargeObject object. - - LargeObject obj = lobj.open(oid,LargeObjectManager.WRITE); - -Once the LargeObject is open, you can call methods to read, write, seek etc. -Here's the supported methods: - - int oid = obj.getOID(); Return the objects oid - obj.close(); Close the object - byte data[] = obj.read(int len); Read len bytes - onj.read(byte data[],int off,int len); Read into data[off] len bytes - obj.write(byte data[]); Write the array data - obj.write(byte data[],int off,int len); Write len bytes from data[off] - obj.seek(int pos,int ref); As fseek in C. - obj.seek(int pos); Move to pos (from the begining) - int pos = obj.tell(); Returns the current position - int size = obj.size(); Returns the objects size - -Caveat: If you commit(), rollback() a transaction, or turn on autocommit whilst -an object is open PostgreSQL will close it. You will need to reopen the object -before using it again. Using the existing LargeObject will cause an -SQLException to be thrown. - - ------------------ - -JDBC supports database specific data types using the getObject() call. The -following types have their own Java equivalents supplied by the driver: - - box, circle, line, lseg, path, point, polygon - -When using the getObject() method on a resultset, it returns a PG_Object, -which holds the postgres type, and its value. This object also supports -methods to retrive these types. - - Eg: column 3 contains a point, and rs is the ResultSet: - - PG_Object o = (PG_Object)rs.getObject(3); - PGpoint p = o.getPoint(); - System.out.println("point returned x="+p.x+", y="+p.y); - -Also, when using these classes, their toString() methods return the correct -syntax for writing these to the database. - ---------------------------------------------------------------------------- - diff --git a/src/interfaces/jdbc/build.xml b/src/interfaces/jdbc/build.xml deleted file mode 100644 index df29d63656f..00000000000 --- a/src/interfaces/jdbc/build.xml +++ /dev/null @@ -1,363 +0,0 @@ -<?xml version="1.0"?> -<!-- - - Build file to allow ant (http://jakarta.apache.org/ant/) to be used - to build the PostgreSQL JDBC Driver. - - This file now requires Ant 1.4.1. 2002-04-18 - - $PostgreSQL: pgsql/src/interfaces/jdbc/build.xml,v 1.38 2003/11/29 19:52:09 pgsql Exp $ - ---> - -<!DOCTYPE project [ - <!ENTITY jarfiles "postgresql.jar,postgresql-examples.jar"> -]> - -<project name="postgresqlJDBC" default="all" basedir="."> - - <!-- set global properties for this build --> - <property name="srcdir" value="." /> - <property name="jardir" value="jars" /> - <property name="builddir" value="build" /> - <property name="package" value="org/postgresql" /> - <property name="debug" value="on" /> - - <property file="build.properties"/> - - <!-- - This is a simpler method than utils.CheckVersion - It defaults to jdbc1, but builds jdbc2 if the java.lang.Byte class is - in the CLASSPATH (ie JDK1.2 or later), and then enterprise if the - javax.sql.DataSource class is present. - - Important: This must have the following order: jdbc1, jdbc2, jdbc3 - --> - <target name="check_versions"> - <condition property="jdbc1"> - <equals arg1="${ant.java.version}" arg2="1.1"/> - </condition> - <condition property="jdbc2"> - <or> - <equals arg1="${ant.java.version}" arg2="1.2"/> - <equals arg1="${ant.java.version}" arg2="1.3"/> - </or> - </condition> - <condition property="jdbc3"> - <equals arg1="${ant.java.version}" arg2="1.4"/> - </condition> - <available property="datasource" classname="javax.sql.DataSource"/> - <available property="ssl" classname="javax.net.ssl.SSLSocketFactory"/> - <available property="junit" classname="junit.framework.Test"/> - <available property="junit.task" classname="org.apache.tools.ant.taskdefs.optional.junit.JUnitTask"/> - <condition property="jdbc2tests"> - <and> - <or> - <isset property="jdbc2"/> - <isset property="jdbc3"/> - </or> - <isset property="junit"/> - </and> - </condition> - <condition property="jdbc2optionaltests"> - <and> - <or> - <isset property="jdbc2"/> - <isset property="jdbc3"/> - </or> - <isset property="datasource"/> - <isset property="junit"/> - </and> - </condition> - <condition property="jdbc3tests"> - <and> - <isset property="jdbc3"/> - <isset property="junit"/> - </and> - </condition> - </target> - - - <!-- default target --> - <target name="all"> - <antcall target="jar" /> - </target> - - - <!-- create the jar file --> - <target name="jar" depends="compile,examples"> - <jar jarfile="${jardir}/postgresql.jar"> - <fileset dir="${builddir}"> - <include name="${package}/**/*.class" /> - </fileset> - - <fileset dir="${srcdir}"> - <include name="${package}/*.properties" /> - </fileset> - </jar> - - <jar jarfile="${jardir}/postgresql-examples.jar"> - <fileset dir="${builddir}"> - <include name="example/**/*.class" /> - </fileset> - - <fileset dir="${srcdir}"> - <include name="example/*.properties" /> - </fileset> - </jar> - </target> - - - <target name="compile" depends="prepare,check_versions,driver"> - - <available classname="org.postgresql.Driver" property="old.driver.present" /> - <fail message="Old driver was detected on classpath or in jre/lib/ext, please remove and try again." if="old.driver.present" /> - - <javac classpath="{$srcdir}" srcdir="${srcdir}" destdir="${builddir}" debug="${debug}"> - <!-- This is the core of the driver. It is common for all three versions. --> - <include name="${package}/*.java" /> - <include name="${package}/core/**" /> - <include name="${package}/fastpath/**" /> - <include name="${package}/geometric/**" /> - <include name="${package}/largeobject/**" /> - <include name="${package}/util/**" /> - - <!-- - Each jdbcN subpackage is used only if the driver supports *at least* that - revision of JDBC. That is, a JDBC1 build uses only jdbc1, a JDBC2 build - uses both jdbc1 and jdbc2, etc. - - Within those subpackages, classes beginning with "JdbcN" are assumed to be - the concrete implementations for JDBC version N and are built only if the - driver supports *exactly* that version. For example, jdbc1/Jdbc1Statement.java - is built only if the driver build is a JDBC1 build. - --> - - <!-- jdbc1 subpackage --> - <include name="${package}/jdbc1/**"/> - <exclude name="${package}/jdbc1/Jdbc1*.java" unless="jdbc1"/> - - <!-- jdbc2 subpackage --> - <include name="${package}/jdbc2/**" if="jdbc2"/> - <include name="${package}/jdbc2/**" if="jdbc3"/> - <exclude name="${package}/jdbc2/Jdbc2*.java" unless="jdbc2"/> - <exclude name="${package}/jdbc2/optional/**" unless="datasource"/> - - <!-- jdbc3 subpackage --> - <include name="${package}/jdbc3/*.java" if="jdbc3"/> - <exclude name="${package}/jdbc3/Jdbc3*.java" unless="jdbc3"/> - - </javac> - </target> - - <target name="check_driver"> - <uptodate targetfile="${package}/Driver.java" property="driver.uptodate"> - <srcfiles dir="."> - <include name="${package}/Driver.java.in"/> - <include name="build.properties"/> - </srcfiles> - </uptodate> - </target> - - <!-- - This generates Driver.java from Driver.java.in - It's required for importing the driver version properties - --> - <target name="driver" depends="prepare,check_versions,check_driver" - unless="driver.uptodate"> - <!-- determine the edition text --> - <condition property="edition" value="JDBC1"> - <equals arg1="${jdbc1}" arg2="true"/> - </condition> - <condition property="edition" value="JDBC2"> - <equals arg1="${jdbc2}" arg2="true"/> - </condition> - <condition property="edition" value="JDBC3"> - <equals arg1="${jdbc3}" arg2="true"/> - </condition> - <condition property="edition" value="JDBC2 Enterprise"> - <and> - <available classname="javax.sql.DataSource" /> - <equals arg1="${jdbc2}" arg2="true"/> - </and> - </condition> - - <!-- determine the connection class --> - <condition property="connectclass" value="org.postgresql.jdbc1.Jdbc1Connection"> - <equals arg1="${jdbc1}" arg2="true"/> - </condition> - <condition property="connectclass" value="org.postgresql.jdbc2.Jdbc2Connection"> - <equals arg1="${jdbc2}" arg2="true"/> - </condition> - <condition property="connectclass" value="org.postgresql.jdbc3.Jdbc3Connection"> - <equals arg1="${jdbc3}" arg2="true"/> - </condition> - - <!-- determine the ssl status --> - <condition property="ssl_config" value=""> - <equals arg1="${ssl}" arg2="true"/> - </condition> - <condition property="ssl_config" value="//"> - <not> - <equals arg1="${ssl}" arg2="true"/> - </not> - </condition> - <condition property="ssl_edition" value="SSL"> - <equals arg1="${ssl}" arg2="true"/> - </condition> - <condition property="ssl_edition" value="NO SSL"> - <not> - <equals arg1="${ssl}" arg2="true"/> - </not> - </condition> - - <!-- Some defaults --> - <filter token="MAJORVERSION" value="${major}" /> - <filter token="MINORVERSION" value="${minor}" /> - <filter token="VERSION" value="PostgreSQL ${fullversion} ${edition} with ${ssl_edition}" /> - <filter token="JDBCCONNECTCLASS" value="${connectclass}" /> - <filter token="DEF_PGPORT" value="${def_pgport}" /> - <filter token="SSL" value="${ssl_config}" /> - - <fail unless="major" message="'major' undefined. Please follow the directions in README."/> - <fail unless="minor" message="'minor' undefined. Please follow the directions in README."/> - <fail unless="fullversion" message="'fullversion' undefined. Please follow the directions in README."/> - <fail unless="def_pgport" message="'def_pgport' undefined. Please follow the directions in README."/> - <fail unless="enable_debug" message="'enable_debug' undefined. Please follow the directions in README."/> - - <!-- Put a check for the current version here --> - - <!-- now copy and filter the file --> - <copy file="${package}/Driver.java.in" - overwrite="true" - tofile="${package}/Driver.java" - filtering="yes" /> - - <echo message="Configured build for the ${edition} edition driver with ${ssl_edition}" /> - </target> - - - <!-- Prepares the build directory --> - <target name="prepare"> - <!-- use the enable_debug option from configure --> - <condition property="debug" value="on"> - <and> - <equals arg1="${enable_debug}" arg2="yes" /> - </and> - </condition> - <mkdir dir="${builddir}" /> - <mkdir dir="${jardir}" /> - </target> - - - <!-- This builds the examples --> - <target name="examples" depends="compile"> - <javac srcdir="${srcdir}" destdir="${builddir}" debug="${debug}"> - <include name="example/**" /> - <exclude name="example/corba/**"/> - <exclude name="example/blobtest.java" if="jdbc1"/> - </javac> - </target> - - - <!-- Builds the corba example --> - <target name="corba" if="jdbc2"> - <exec dir="${srcdir}/example/corba" executable="idl2java"> - <arg value="stock.idl" /> - </exec> - - <javac srcdir="${srcdir}" destdir="${builddir}" debug="${debug}"> - <include name="example/corba/**" /> - </javac> - </target> - - - - <!-- Install the jar files --> - <target name="install" depends="all" if="install.directory"> - <copy todir="${install.directory}" overwrite="true"> - <fileset dir="${jardir}" includes="&jarfiles;" /> - </copy> - </target> - - - <!-- Uninstall the jar file --> - <target name="uninstall" if="install.directory"> - <delete> - <fileset dir="${install.directory}" includes="&jarfiles;" /> - </delete> - </target> - - - - <!-- This target removes any class files from the build directory --> - <target name="clean"> - <delete quiet="true" dir="${builddir}" /> - <delete quiet="true" dir="${jardir}" /> - <delete quiet="true" file="${package}/Driver.java" /> - </target> - - <target name="clean_all" depends="clean"> - <delete quiet="true" file="build.properties" /> - </target> - - - <!-- This compiles and executes the JUnit tests --> - - <!-- defaults for the tests - override these if required --> - <property name="server" value="localhost" /> - <property name="port" value="${def_pgport}" /> - <property name="database" value="test" /> - <property name="username" value="test" /> - <!-- Password must be something. Doesn't matter if trust is used! --> - <property name="password" value="password" /> - - <!-- The tests now build to a separate directory and jarfile from the - driver build, to ensure we're really testing against the jar we just - built, and not whatever happens to be in builddir. --> - - <!-- This compiles and builds the test jarfile. --> - <target name="testjar" depends="jar" if="junit"> - <mkdir dir="${builddir}/tests"/> - <javac srcdir="${srcdir}" destdir="${builddir}/tests" debug="${debug}"> - <include name="${package}/test/**" /> - - <exclude name="${package}/test/jdbc2/**" unless="jdbc2tests"/> - <exclude name="${package}/test/jdbc2/optional/**" unless="jdbc2optionaltests" /> - <exclude name="${package}/test/jdbc3/**" unless="jdbc3tests" /> - <exclude name="${package}/test/util/**" unless="jdbc2optionaltests"/> - - <classpath> - <pathelement location="${jardir}/postgresql.jar"/> - </classpath> - </javac> - <jar jarfile="${jardir}/postgresql-tests.jar" basedir="${builddir}/tests"/> - </target> - - <!-- This actually runs the tests --> - <target name="runtest" depends="testjar" if="junit.task"> - <junit> - <formatter type="brief" usefile="false"/> - - <sysproperty key="server" value="${server}" /> - <sysproperty key="port" value="${port}" /> - <sysproperty key="database" value="${database}" /> - <sysproperty key="username" value="${username}" /> - <sysproperty key="password" value="${password}" /> - - <classpath> - <pathelement location="${jardir}/postgresql.jar" /> - <pathelement location="${jardir}/postgresql-tests.jar" /> - <pathelement path="${java.class.path}" /> - </classpath> - - <test name="org.postgresql.test.jdbc2.Jdbc2TestSuite" if="jdbc2tests"/> - <test name="org.postgresql.test.jdbc2.optional.OptionalTestSuite" if="jdbc2optionaltests"/> - <test name="org.postgresql.test.jdbc3.Jdbc3TestSuite" if="jdbc3tests"/> - </junit> - </target> - - <!-- This is the target invoked by the Makefile --> - <target name="test" depends="testjar,runtest"/> - -</project> diff --git a/src/interfaces/jdbc/example/ImageViewer.java b/src/interfaces/jdbc/example/ImageViewer.java deleted file mode 100644 index 0401780b5ca..00000000000 --- a/src/interfaces/jdbc/example/ImageViewer.java +++ /dev/null @@ -1,517 +0,0 @@ -package example; - -import java.awt.*; -import java.awt.event.*; -import java.io.*; -import java.sql.*; -import org.postgresql.largeobject.*; - -/* - * This example is a small application that stores and displays images - * held on a postgresql database. - * - * Before running this application, you need to create a database, and - * on the first time you run it, select "Initialise" in the "PostgreSQL" - * menu. - * - * Important note: You will notice we import the org.postgresql.largeobject - * package, but don't import the org.postgresql package. The reason for this is - * that importing postgresql can confuse javac (we have conflicting class names - * in org.postgresql.* and java.sql.*). This doesn't cause any problems, as - * long as no code imports org.postgresql. - * - * Under normal circumstances, code using any jdbc driver only needs to import - * java.sql, so this isn't a problem. - * - * It's only if you use the non jdbc facilities, do you have to take this into - * account. - * - * Note: For PostgreSQL 6.4, the driver is now Thread safe, so this example - * application has been updated to use multiple threads, especially in the - * image storing and retrieving methods. - */ - -public class ImageViewer implements ItemListener -{ - Connection db; - Statement stat; - LargeObjectManager lom; - Frame frame; - Label label; // Label used to display the current name - List list; // The list of available images - imageCanvas canvas; // Canvas used to display the image - String currentImage; // The current images name - - // This is a simple component to display our image - public class imageCanvas extends Canvas - { - // holds the image - private Image image; - - // holds the background buffer - private Image bkg; - - // the size of the buffer - private Dimension size; - - public imageCanvas() - { - image = null; - } - - public void setImage(Image img) - { - image = img; - repaint(); - } - - // This defines our minimum size - public Dimension getMinimumSize() - { - return new Dimension(400, 400); - } - - public Dimension getPreferedSize() - { - return getMinimumSize(); - } - - public void update(Graphics g) - { - paint(g); - } - - /* - * Paints the image, using double buffering to prevent screen flicker - */ - public void paint(Graphics gr) - { - Dimension s = getSize(); - - if (size == null || bkg == null || !s.equals(size)) - { - size = s; - bkg = createImage(size.width, size.height); - } - - // now set the background - Graphics g = bkg.getGraphics(); - g.setColor(Color.gray); - g.fillRect(0, 0, s.width, s.height); - - // now paint the image over the background - if (image != null) - g.drawImage(image, 0, 0, this); - - // dispose the graphics instance - g.dispose(); - - // paint the image onto the component - gr.drawImage(bkg, 0, 0, this); - - } - - } - - public ImageViewer(Frame f, String url, String user, String password) throws ClassNotFoundException, FileNotFoundException, IOException, SQLException - { - frame = f; - - MenuBar mb = new MenuBar(); - Menu m; - MenuItem i; - - f.setMenuBar(mb); - mb.add(m = new Menu("PostgreSQL")); - m.add(i = new MenuItem("Initialise")); - i.addActionListener(new ActionListener() - { - public void actionPerformed(ActionEvent e) - { - ImageViewer.this.init(); - } - } - ); - - m.add(i = new MenuItem("Exit")); - ActionListener exitListener = new ActionListener() - { - public void actionPerformed(ActionEvent e) - { - ImageViewer.this.close(); - } - }; - m.addActionListener(exitListener); - - mb.add(m = new Menu("Image")); - m.add(i = new MenuItem("Import")); - ActionListener importListener = new ActionListener() - { - public void actionPerformed(ActionEvent e) - { - ImageViewer.this.importImage(); - } - }; - i.addActionListener(importListener); - - m.add(i = new MenuItem("Remove")); - ActionListener removeListener = new ActionListener() - { - public void actionPerformed(ActionEvent e) - { - ImageViewer.this.removeImage(); - } - }; - i.addActionListener(removeListener); - - // To the north is a label used to display the current images name - f.add("North", label = new Label()); - - // We have a panel to the south of the frame containing the controls - Panel p = new Panel(); - p.setLayout(new FlowLayout()); - Button b; - p.add(b = new Button("Refresh List")); - b.addActionListener(new ActionListener() - { - public void actionPerformed(ActionEvent e) - { - ImageViewer.this.refreshList(); - } - } - ); - p.add(b = new Button("Import new image")); - b.addActionListener(importListener); - p.add(b = new Button("Remove image")); - b.addActionListener(removeListener); - p.add(b = new Button("Quit")); - b.addActionListener(exitListener); - f.add("South", p); - - // And a panel to the west containing the list of available images - f.add("West", list = new List()); - list.addItemListener(this); - - // Finally the centre contains our image - f.add("Center", canvas = new imageCanvas()); - - // Load the driver - Class.forName("org.postgresql.Driver"); - - // Connect to database - db = DriverManager.getConnection(url, user, password); - - // Create a statement - stat = db.createStatement(); - - // Also, get the LargeObjectManager for this connection - lom = ((org.postgresql.PGConnection)db).getLargeObjectAPI(); - - // Now refresh the image selection list - refreshList(); - } - - - /* - * This method initialises the database by creating a table that contains - * the image names, and Large Object OID's - */ - public void init() - { - try - { - //db.setAutoCommit(true); - stat.executeUpdate("create table images (imgname name,imgoid oid)"); - label.setText("Initialised database"); - db.commit(); - } - catch (SQLException ex) - { - label.setText(ex.toString()); - } - - // This must run outside the previous try{} catch{} segment - //try { - //db.setAutoCommit(true); - //} catch(SQLException ex) { - //label.setText(ex.toString()); - //} - } - - /* - * This closes the connection, and ends the application - */ - public void close() - { - try - { - db.close(); - } - catch (SQLException ex) - { - System.err.println(ex.toString()); - } - System.exit(0); - } - - /* - * This imports an image into the database, using a Thread to do this in the - * background. - */ - public void importImage() - { - FileDialog d = new FileDialog(frame, "Import Image", FileDialog.LOAD); - d.setVisible(true); - String name = d.getFile(); - String dir = d.getDirectory(); - d.dispose(); - - // now start the true importer - Thread t = new importer(db, name, dir); - //t.setPriority(Thread.MAX_PRIORITY); - t.start(); - } - - /* - * This is an example of using a thread to import a file into a Large Object. - * It uses the Large Object extension, to write blocks of the file to the - * database. - */ - class importer extends Thread - { - String name, dir; - Connection db; - - public importer(Connection db, String name, String dir) - { - this.db = db; - this.name = name; - this.dir = dir; - } - - public void run() - { - // Now the real import stuff - if (name != null && dir != null) - { - Statement stat = null; - - try - { - // fetch the large object manager - LargeObjectManager lom = ((org.postgresql.PGConnection)db).getLargeObjectAPI(); - - db.setAutoCommit(false); - - // A temporary buffer - this can be as large as you like - byte buf[] = new byte[2048]; - - // Open the file - FileInputStream fis = new FileInputStream(new File(dir, name)); - - // Now create the large object - int oid = lom.create(); - LargeObject blob = lom.open(oid); - - // Now copy the file into the object. - // - // Note: we dont use write(buf), as the last block is rarely the same - // size as our buffer, so we have to use the amount read. - int s, t = 0; - while ((s = fis.read(buf, 0, buf.length)) > 0) - { - t += s; - blob.write(buf, 0, s); - } - - // Close the object - blob.close(); - - // Now store the entry into the table - - // As we are a different thread to the other window, we must use - // our own thread - stat = db.createStatement(); - stat.executeUpdate("insert into images values ('" + name + "'," + oid + ")"); - db.commit(); - db.setAutoCommit(false); - - // Finally refresh the names list, and display the current image - ImageViewer.this.refreshList(); - ImageViewer.this.displayImage(name); - } - catch (Exception ex) - { - label.setText(ex.toString()); - } - finally - { - // ensure the statement is closed after us - try - { - if (stat != null) - stat.close(); - } - catch (SQLException se) - { - System.err.println("closing of Statement failed"); - } - } - } - } - } - - /* - * This refreshes the list of available images - */ - public void refreshList() - { - try - { - // First, we'll run a query, retrieving all of the image names - ResultSet rs = stat.executeQuery("select imgname from images order by imgname"); - if (rs != null) - { - list.removeAll(); - while (rs.next()) - list.addItem(rs.getString(1)); - rs.close(); - } - } - catch (SQLException ex) - { - label.setText(ex.toString() + " Have you initialised the database?"); - } - } - - /* - * This removes an image from the database - * - * Note: With postgresql, this is the only way of deleting a large object - * using Java. - */ - public void removeImage() - { - try - { - // - // Delete any large objects for the current name - // - // Note: We don't need to worry about being in a transaction - // here, because we are not opening any blobs, only deleting - // them - // - ResultSet rs = stat.executeQuery("select imgoid from images where imgname='" + currentImage + "'"); - if (rs != null) - { - // Even though there should only be one image, we still have to - // cycle through the ResultSet - while (rs.next()) - { - lom.delete(rs.getInt(1)); - } - } - rs.close(); - - // Finally delete any entries for that name - stat.executeUpdate("delete from images where imgname='" + currentImage + "'"); - - label.setText(currentImage + " deleted"); - currentImage = null; - refreshList(); - } - catch (SQLException ex) - { - label.setText(ex.toString()); - } - } - - /* - * This displays an image from the database. - * - * For images, this is the easiest method. - */ - public void displayImage(String name) - { - try - { - // - // Now as we are opening and reading a large object we must - // turn on Transactions. This includes the ResultSet.getBytes() - // method when it's used on a field of type oid! - // - db.setAutoCommit(false); - - ResultSet rs = stat.executeQuery("select imgoid from images where imgname='" + name + "'"); - if (rs != null) - { - // Even though there should only be one image, we still have to - // cycle through the ResultSet - while (rs.next()) - { - canvas.setImage(canvas.getToolkit().createImage(rs.getBytes(1))); - label.setText(currentImage = name); - } - } - rs.close(); - } - catch (SQLException ex) - { - label.setText(ex.toString()); - } - finally - { - try - { - db.setAutoCommit(true); - } - catch (SQLException ex2) - {} - } - } - - public void itemStateChanged(ItemEvent e) - { - displayImage(list.getItem(((Integer)e.getItem()).intValue())); - } - - /* - * This is the command line instructions - */ - public static void instructions() - { - System.err.println("java example.ImageViewer jdbc-url user password"); - System.err.println("\nExamples:\n"); - System.err.println("java -Djdbc.driver=org.postgresql.Driver example.ImageViewer jdbc:postgresql:test postgres password\n"); - - System.err.println("This example tests the binary large object api of the driver.\nBasically, it will allow you to store and view images held in the database."); - System.err.println("Note: If you are running this for the first time on a particular database,\nyou have to select \"Initialise\" in the \"PostgreSQL\" menu.\nThis will create a table used to store image names."); - } - - /* - * This is the application entry point - */ - public static void main(String args[]) - { - if (args.length != 3) - { - instructions(); - System.exit(1); - } - - try - { - Frame frame = new Frame("PostgreSQL ImageViewer v7.0 rev 1"); - frame.setLayout(new BorderLayout()); - ImageViewer viewer = new ImageViewer(frame, args[0], args[1], args[2]); - frame.pack(); - frame.setLocation(0, 50); - frame.setVisible(true); - } - catch (Exception ex) - { - System.err.println("Exception caught.\n" + ex); - ex.printStackTrace(); - } - } -} diff --git a/src/interfaces/jdbc/example/Unicode.java b/src/interfaces/jdbc/example/Unicode.java deleted file mode 100644 index b1d1db299c6..00000000000 --- a/src/interfaces/jdbc/example/Unicode.java +++ /dev/null @@ -1,276 +0,0 @@ -package example; - -import java.sql.*; -import java.util.*; - -/* - * Test inserting and extracting Unicode-encoded strings. - * - * Synopsis: - * example.Unicode <url> <user> <password> - * where <url> must specify an existing database to which <user> and - * <password> give access and which has UNICODE as its encoding. - * (To create a database with UNICODE encoding, you need to run createdb - * with the flag "-E UNICODE".) - * - * This test only produces output on error. - * - * @author William Webber <[email protected]> - */ -public class Unicode -{ - - /* - * The url for the database to connect to. - */ - private String url; - - /* - * The user to connect as. - */ - private String user; - - /* - * The password to connect with. - */ - private String password; - - private static void usage() - { - log("usage: example.Unicode <url> <user> <password>"); - } - - private static void log(String message) - { - System.err.println(message); - } - - private static void log(String message, Exception e) - { - System.err.println(message); - e.printStackTrace(); - } - - - public Unicode(String url, String user, String password) - { - this.url = url; - this.user = user; - this.password = password; - } - - /* - * Establish and return a connection to the database. - */ - private Connection getConnection() throws SQLException, - ClassNotFoundException - { - Class.forName("org.postgresql.Driver"); - Properties info = new Properties(); - info.put("user", user); - info.put("password", password); - info.put("charSet", "utf-8"); - return DriverManager.getConnection(url, info); - } - - /* - * Get string representing a block of 256 consecutive unicode characters. - * We exclude the null character, "'", and "\". - */ - private String getSqlSafeUnicodeBlock(int blockNum) - { - if (blockNum < 0 || blockNum > 255) - throw new IllegalArgumentException("blockNum must be from 0 to " - + "255: " + blockNum); - StringBuffer sb = new StringBuffer(256); - int blockFirst = blockNum * 256; - int blockLast = blockFirst + 256; - for (int i = blockFirst; i < blockLast; i++) - { - char c = (char) i; - if (c == '\0' || c == '\'' || c == '\\') - continue; - sb.append(c); - } - return sb.toString(); - } - - /* - * Is the block a block of valid unicode values. - * d800 to db7f is the "unassigned high surrogate" range. - * db80 to dbff is the "private use" range. - * These should not be used in actual Unicode strings; - * at least, jdk1.2 will not convert them to utf-8. - */ - private boolean isValidUnicodeBlock(int blockNum) - { - if (blockNum >= 0xd8 && blockNum <= 0xdb) - return false; - else - return true; - } - - /* - * Report incorrect block retrieval. - */ - private void reportRetrievalError(int blockNum, String block, - String retrieved) - { - String message = "Block " + blockNum + " returned incorrectly: "; - int i = 0; - for (i = 0; i < block.length(); i++) - { - if (i >= retrieved.length()) - { - message += "too short"; - break; - } - else if (retrieved.charAt(i) != block.charAt(i)) - { - message += - "first changed character at position " + i + ", sent as 0x" - + Integer.toHexString((int) block.charAt(i)) - + ", retrieved as 0x" - + Integer.toHexString ((int) retrieved.charAt(i)); - break; - } - } - if (i >= block.length()) - message += "too long"; - log(message); - } - - /* - * Do the testing. - */ - public void runTest() - { - Connection connection = null; - Statement statement = null; - int blockNum = 0; - final int CREATE = 0; - final int INSERT = 1; - final int SELECT = 2; - final int LIKE = 3; - int mode = CREATE; - try - { - connection = getConnection(); - statement = connection.createStatement(); - statement.executeUpdate("CREATE TABLE test_unicode " - + "( blockNum INT PRIMARY KEY, " - + "block TEXT );"); - mode = INSERT; - for (blockNum = 0; blockNum < 256; blockNum++) - { - if (isValidUnicodeBlock(blockNum)) - { - String block = getSqlSafeUnicodeBlock(blockNum); - statement.executeUpdate - ("INSERT INTO test_unicode VALUES ( " + blockNum - + ", '" + block + "');"); - } - } - mode = SELECT; - for (blockNum = 0; blockNum < 256; blockNum++) - { - if (isValidUnicodeBlock(blockNum)) - { - String block = getSqlSafeUnicodeBlock(blockNum); - ResultSet rs = statement.executeQuery - ("SELECT block FROM test_unicode WHERE blockNum = " - + blockNum + ";"); - if (!rs.next()) - log("Could not retrieve block " + blockNum); - else - { - String retrieved = rs.getString(1); - if (!retrieved.equals(block)) - { - reportRetrievalError(blockNum, block, retrieved); - } - } - } - } - mode = LIKE; - for (blockNum = 0; blockNum < 256; blockNum++) - { - if (isValidUnicodeBlock(blockNum)) - { - String block = getSqlSafeUnicodeBlock(blockNum); - String likeString = "%" + - block.substring(2, block.length() - 3) + "%" ; - ResultSet rs = statement.executeQuery - ("SELECT blockNum FROM test_unicode WHERE block LIKE '" - + likeString + "';"); - if (!rs.next()) - log("Could get block " + blockNum + " using LIKE"); - } - } - } - catch (SQLException sqle) - { - switch (mode) - { - case CREATE: - log("Exception creating database", sqle); - break; - case INSERT: - log("Exception inserting block " + blockNum, sqle); - break; - case SELECT: - log("Exception selecting block " + blockNum, sqle); - break; - case LIKE: - log("Exception doing LIKE on block " + blockNum, sqle); - break; - default: - log("Exception", sqle); - break; - } - } - catch (ClassNotFoundException cnfe) - { - log("Unable to load driver", cnfe); - return ; - } - try - { - if (statement != null) - statement.close(); - if (connection != null) - connection.close(); - } - catch (SQLException sqle) - { - log("Exception closing connections", sqle); - } - if (mode > CREATE) - { - // If the backend gets what it regards as garbage on a connection, - // that connection may become unusable. To be safe, we create - // a fresh connection to delete the table. - try - { - connection = getConnection(); - statement = connection.createStatement(); - statement.executeUpdate("DROP TABLE test_unicode;"); - } - catch (Exception sqle) - { - log("*** ERROR: unable to delete test table " - + "test_unicode; must be deleted manually", sqle); - } - } - } - - public static void main(String [] args) - { - if (args.length != 3) - { - usage(); - System.exit(1); - } - new Unicode(args[0], args[1], args[2]).runTest(); - } -} diff --git a/src/interfaces/jdbc/example/basic.java b/src/interfaces/jdbc/example/basic.java deleted file mode 100644 index d1a7e602941..00000000000 --- a/src/interfaces/jdbc/example/basic.java +++ /dev/null @@ -1,219 +0,0 @@ -package example; - -import java.io.*; -import java.sql.*; - -/* - * - * $PostgreSQL: pgsql/src/interfaces/jdbc/example/basic.java,v 1.15 2003/11/29 22:41:19 pgsql Exp $ - * - * This example tests the basic components of the JDBC driver, and shows - * how even the simplest of queries can be implemented. - * - * To use this example, you need a database to be in existence. This example - * will create a table called basic. - * - * Note: This will only work with post 7.0 drivers. - * - */ - -public class basic -{ - Connection db; // The connection to the database - Statement st; // Our statement to run queries with - - public basic(String args[]) throws ClassNotFoundException, FileNotFoundException, IOException, SQLException - { - String url = args[0]; - String usr = args[1]; - String pwd = args[2]; - - // Load the driver - Class.forName("org.postgresql.Driver"); - - // Connect to database - System.out.println("Connecting to Database URL = " + url); - db = DriverManager.getConnection(url, usr, pwd); - - System.out.println("Connected...Now creating a statement"); - st = db.createStatement(); - - // Clean up the database (in case we failed earlier) then initialise - cleanup(); - - // Now run tests using JDBC methods - doexample(); - - // Clean up the database - cleanup(); - - // Finally close the database - System.out.println("Now closing the connection"); - st.close(); - db.close(); - - //throw postgresql.Driver.notImplemented(); - } - - /* - * This drops the table (if it existed). No errors are reported. - */ - public void cleanup() - { - try - { - st.executeUpdate("drop table basic"); - } - catch (Exception ex) - { - // We ignore any errors here - } - } - - /* - * This performs the example - */ - public void doexample() throws SQLException - { - System.out.println("\nRunning tests:"); - - // First we need a table to store data in - st.executeUpdate("create table basic (a int2, b int2)"); - - // Now insert some data, using the Statement - st.executeUpdate("insert into basic values (1,1)"); - st.executeUpdate("insert into basic values (2,1)"); - st.executeUpdate("insert into basic values (3,1)"); - - // This shows how to get the oid of a just inserted row - st.executeUpdate("insert into basic values (4,1)"); - long insertedOID = ((org.postgresql.PGStatement)st).getLastOID(); - System.out.println("Inserted row with oid " + insertedOID); - - // Now change the value of b from 1 to 8 - st.executeUpdate("update basic set b=8"); - System.out.println("Updated " + st.getUpdateCount() + " rows"); - - // Now delete 2 rows - st.executeUpdate("delete from basic where a<3"); - System.out.println("deleted " + st.getUpdateCount() + " rows"); - - // For large inserts, a PreparedStatement is more efficient, because it - // supports the idea of precompiling the SQL statement, and to store - // directly, a Java object into any column. PostgreSQL doesnt support - // precompiling, but does support setting a column to the value of a - // Java object (like Date, String, etc). - // - // Also, this is the only way of writing dates in a datestyle independent - // manner. (DateStyles are PostgreSQL's way of handling different methods - // of representing dates in the Date data type.) - PreparedStatement ps = db.prepareStatement("insert into basic values (?,?)"); - for (int i = 2;i < 5;i++) - { - ps.setInt(1, 4); // "column a" = 5 - ps.setInt(2, i); // "column b" = i - ps.executeUpdate(); // executeUpdate because insert returns no data - } - ps.close(); // Always close when we are done with it - - // Finally perform a query on the table - System.out.println("performing a query"); - ResultSet rs = st.executeQuery("select a, b from basic"); - if (rs != null) - { - // Now we run through the result set, printing out the result. - // Note, we must call .next() before attempting to read any results - while (rs.next()) - { - int a = rs.getInt("a"); // This shows how to get the value by name - int b = rs.getInt(2); // This shows how to get the value by column - System.out.println(" a=" + a + " b=" + b); - } - rs.close(); // again, you must close the result when done - } - - // Now run the query again, showing a more efficient way of getting the - // result if you don't know what column number a value is in - - - - System.out.println("performing another query"); - rs = st.executeQuery("select * from basic where b>1"); - if (rs != null) - { - // First find out the column numbers. - // - // It's best to do this here, as calling the methods with the column - // numbers actually performs this call each time they are called. This - // really speeds things up on large queries. - // - int col_a = rs.findColumn("a"); - int col_b = rs.findColumn("b"); - - // Now we run through the result set, printing out the result. - // Again, we must call .next() before attempting to read any results - while (rs.next()) - { - int a = rs.getInt(col_a); // This shows how to get the value by name - int b = rs.getInt(col_b); // This shows how to get the value by column - System.out.println(" a=" + a + " b=" + b); - } - rs.close(); // again, you must close the result when done - } - - // Now test maxrows by setting it to 3 rows - - - - st.setMaxRows(3); - System.out.println("performing a query limited to " + st.getMaxRows()); - rs = st.executeQuery("select a, b from basic"); - while (rs.next()) - { - int a = rs.getInt("a"); // This shows how to get the value by name - int b = rs.getInt(2); // This shows how to get the value by column - System.out.println(" a=" + a + " b=" + b); - } - rs.close(); // again, you must close the result when done - - // The last thing to do is to drop the table. This is done in the - // cleanup() method. - } - - /* - * Display some instructions on how to run the example - */ - public static void instructions() - { - System.out.println("\nThis example tests the basic components of the JDBC driver, demonstrating\nhow to build simple queries in java.\n"); - System.out.println("Useage:\n java example.basic jdbc:postgresql:database user password [debug]\n\nThe debug field can be anything. It's presence will enable DriverManager's\ndebug trace. Unless you want to see screens of items, don't put anything in\nhere."); - System.exit(1); - } - - /* - * This little lot starts the test - */ - public static void main(String args[]) - { - System.out.println("PostgreSQL basic test v6.3 rev 1\n"); - - if (args.length < 3) - instructions(); - - // This line outputs debug information to stderr. To enable this, simply - // add an extra parameter to the command line - if (args.length > 3) - DriverManager.setLogStream(System.err); - - // Now run the tests - try - { - basic test = new basic(args); - } - catch (Exception ex) - { - System.err.println("Exception caught.\n" + ex); - ex.printStackTrace(); - } - } -} diff --git a/src/interfaces/jdbc/example/blobtest.java b/src/interfaces/jdbc/example/blobtest.java deleted file mode 100644 index d517d267b75..00000000000 --- a/src/interfaces/jdbc/example/blobtest.java +++ /dev/null @@ -1,255 +0,0 @@ -package example; - -import java.io.*; -import java.sql.*; -import org.postgresql.largeobject.*; - -/* - * This test attempts to create a blob in the database, then to read - * it back. - * - * Important note: You will notice we import the org.postgresql.largeobject - * package, but don't import the org.postgresql package. The reason for this is - * that importing postgresql can confuse javac (we have conflicting class names - * in org.postgresql.* and java.sql.*). This doesn't cause any problems, as - * long as no code imports org.postgresql. - * - * Under normal circumstances, code using any jdbc driver only needs to import - * java.sql, so this isn't a problem. - * - * It's only if you use the non jdbc facilities, do you have to take this into - * account. - * - */ - -public class blobtest -{ - Connection db; - Statement s; - LargeObjectManager lobj; - - public blobtest(String args[]) throws ClassNotFoundException, FileNotFoundException, IOException, SQLException - { - String url = args[0]; - String usr = args[1]; - String pwd = args[2]; - - // Load the driver - Class.forName("org.postgresql.Driver"); - - // Connect to database - System.out.println("Connecting to Database URL = " + url); - db = DriverManager.getConnection(url, usr, pwd); - - // This is required for all LargeObject calls - System.out.println("Connected... First turn off autoCommit()"); - db.setAutoCommit(false); - - System.out.println("Now creating a statement"); - s = db.createStatement(); - - // Now run tests using postgresql's own Large object api - // NOTE: The methods shown in this example are _NOT_ JDBC, but are - // an implementation of the calls found in libpq. Unless you need to - // use this functionality, look at the jdbc tests on how to access blobs. - ownapi(); - - // Now run tests using JDBC methods - //jdbcapi(db,s); - - // Finally close the database - System.out.println("Now closing the connection"); - s.close(); - db.close(); - } - - /* - * Now this is an extension to JDBC, unique to postgresql. Here we fetch - * an PGlobj object, which provides us with access to postgresql's - * large object api. - */ - public void ownapi() throws FileNotFoundException, IOException, SQLException - { - System.out.println("\n----------------------------------------------------------------------\nTesting postgresql large object api\n----------------------------------------------------------------------\n"); - - // Internally, the driver provides JDBC compliant methods to access large - // objects, however the unique methods available to postgresql makes - // things a little easier. - System.out.println("Gaining access to large object api"); - lobj = ((org.postgresql.PGConnection)db).getLargeObjectAPI(); - - int oid = ownapi_test1(); - ownapi_test2(oid); - - // Now call the jdbc2api test - jdbc2api(oid); - - // finally delete the large object - ownapi_test3(oid); - System.out.println("\n\nOID=" + oid); - } - - private int ownapi_test1() throws FileNotFoundException, IOException, SQLException - { - System.out.println("Test 1 Creating a large object\n"); - - // Ok, test 1 is to create a large object. To do this, we use the create - // method. - System.out.println("Creating a large object"); - int oid = lobj.create(LargeObjectManager.READ | LargeObjectManager.WRITE); - DriverManager.println("got large object oid=" + oid); - - LargeObject obj = lobj.open(oid, LargeObjectManager.WRITE); - DriverManager.println("got large object obj=" + obj); - - // Now open a test file - this class will do - System.out.println("Opening test source object"); - FileInputStream fis = new FileInputStream("example/blobtest.java"); - - // copy the data - System.out.println("Copying file to large object"); - byte buf[] = new byte[2048]; - int s, tl = 0; - while ((s = fis.read(buf, 0, 2048)) > 0) - { - System.out.println("Block size=" + s + " offset=" + tl); - //System.out.write(buf); - obj.write(buf, 0, s); - tl += s; - } - DriverManager.println("Copied " + tl + " bytes"); - - // Close the object - System.out.println("Closing object"); - obj.close(); - - return oid; - } - - private void ownapi_test2(int oid) throws FileNotFoundException, IOException, SQLException - { - System.out.println("Test 2 Reading a large object and save as a file\n"); - - // Now open the large object - System.out.println("Opening large object " + oid); - LargeObject obj = lobj.open(oid, LargeObjectManager.READ); - DriverManager.println("got obj=" + obj); - - // Now open a test file - this class will do - System.out.println("Opening test destination object"); - FileOutputStream fos = new FileOutputStream("blob_testoutput"); - - // copy the data - System.out.println("Copying large object to file"); - byte buf[] = new byte[512]; - int s = obj.size(); - int tl = 0; - while (s > 0) - { - int rs = buf.length; - if (s < rs) - rs = s; - obj.read(buf, 0, rs); - fos.write(buf, 0, rs); - tl += rs; - s -= rs; - } - DriverManager.println("Copied " + tl + "/" + obj.size() + " bytes"); - - // Close the object - System.out.println("Closing object"); - obj.close(); - } - - private void ownapi_test3(int oid) throws SQLException - { - System.out.println("Test 3 Deleting a large object\n"); - - // Now open the large object - System.out.println("Deleting large object " + oid); - lobj.unlink(oid); - } - - // This tests the Blob interface of the JDBC 2.0 specification - public void jdbc2api(int oid) throws SQLException, IOException - { - System.out.println("Testing JDBC2 Blob interface:"); - jdbc2api_cleanup(); - - System.out.println("Creating Blob on large object " + oid); - s.executeUpdate("create table basic (a oid)"); - - System.out.println("Inserting row"); - s.executeUpdate("insert into basic values (" + oid + ")"); - - System.out.println("Selecting row"); - ResultSet rs = s.executeQuery("select a from basic"); - if (rs != null) - { - while (rs.next()) - { - System.out.println("Fetching Blob"); - Blob b = rs.getBlob("a"); - System.out.println("Blob.length() = " + b.length()); - System.out.println("Characters 400-500:"); - System.out.write(b.getBytes(400l, 100)); - System.out.println(); - } - rs.close(); - } - - System.out.println("Cleaning up"); - jdbc2api_cleanup(); - } - - private void jdbc2api_cleanup() throws SQLException - { - db.setAutoCommit(true); - try - { - s.executeUpdate("drop table basic"); - } - catch (Exception ex) - { - // We ignore any errors here - } - db.setAutoCommit(false); - } - - public static void instructions() - { - System.err.println("java example.blobtest jdbc-url user password [debug]"); - System.err.println("\nExamples:\n"); - System.err.println("java -Djdbc.driver=org.postgresql.Driver example.blobtest jdbc:postgresql:test postgres password\nThis will run the tests on the database test on the local host.\n"); - System.err.println("java -Djdbc.driver=org.postgresql.Driver example.blobtest jdbc:postgresql:test postgres password debug\nThis is the same as above, but will output debug information.\n"); - - System.err.println("This example tests the binary large object api of the driver.\nThis allows images or java objects to be stored in the database, and retrieved\nusing both postgresql's own api, and the standard JDBC api."); - } - - public static void main(String args[]) - { - System.out.println("PostgreSQL blobtest v7.0 rev 1\n"); - - if (args.length < 3) - { - instructions(); - System.exit(1); - } - - // This line outputs debug information to stderr. To enable this, simply - // add an extra parameter to the command line - if (args.length > 3) - DriverManager.setLogStream(System.err); - - // Now run the tests - try - { - blobtest test = new blobtest(args); - } - catch (Exception ex) - { - System.err.println("Exception caught.\n" + ex); - ex.printStackTrace(); - } - } -} diff --git a/src/interfaces/jdbc/example/corba/StockClient.java b/src/interfaces/jdbc/example/corba/StockClient.java deleted file mode 100644 index 217552f0810..00000000000 --- a/src/interfaces/jdbc/example/corba/StockClient.java +++ /dev/null @@ -1,348 +0,0 @@ -package example.corba; - -import java.io.*; -import java.sql.*; -import org.omg.CosNaming.*; - -/* - * This class is the frontend to our mini CORBA application. - * - * It has no GUI, just a text frontend to keep it simple. - * - * $PostgreSQL: pgsql/src/interfaces/jdbc/example/corba/StockClient.java,v 1.7 2003/11/29 22:41:21 pgsql Exp $ - */ -public class StockClient -{ - org.omg.CosNaming.NamingContext nameService; - - stock.StockDispenser dispenser; - stock.StockItem item; - - BufferedReader in; - - public StockClient(String[] args) - { - try - { - // We need this for our IO - in = new BufferedReader(new InputStreamReader(System.in)); - - // Initialize the orb - org.omg.CORBA.ORB orb = org.omg.CORBA.ORB.init(args, null); - - // Get a reference to the Naming Service - org.omg.CORBA.Object nameServiceObj = orb.resolve_initial_references("NameService"); - if (nameServiceObj == null) - { - System.err.println("nameServiceObj == null"); - return ; - } - - nameService = org.omg.CosNaming.NamingContextHelper.narrow(nameServiceObj); - if (nameService == null) - { - System.err.println("nameService == null"); - return ; - } - - // Resolve the dispenser - NameComponent[] dispName = { - new NameComponent("StockDispenser", "Stock") - }; - dispenser = stock.StockDispenserHelper.narrow(nameService.resolve(dispName)); - if (dispenser == null) - { - System.err.println("dispenser == null"); - return ; - } - - // Now run the front end. - run(); - } - catch (Exception e) - { - System.out.println(e.toString()); - e.printStackTrace(); - System.exit(1); - } - } - - public static void main(String[] args) - { - new StockClient(args); - } - - public void run() - { - // First reserve a StockItem - try - { - item = dispenser.reserveItem(); - } - catch (Exception e) - { - System.out.println(e.toString()); - e.printStackTrace(); - System.exit(1); - } - - mainMenu(); - - // finally free the StockItem - try - { - dispenser.releaseItem(item); - } - catch (Exception e) - { - System.out.println(e.toString()); - e.printStackTrace(); - System.exit(1); - } - } - - private void mainMenu() - { - boolean run = true; - while (run) - { - System.out.println("\nCORBA Stock System\n"); - System.out.println(" 1 Display stock item"); - System.out.println(" 2 Remove item from stock"); - System.out.println(" 3 Put item into stock"); - System.out.println(" 4 Order item"); - System.out.println(" 5 Display all items"); - System.out.println(" 0 Exit"); - int i = getMenu("Main", 5); - switch (i) - { - case 0: - run = false; - break; - - case 1: - displayItem(); - break; - - case 2: - bookOut(); - break; - - case 3: - bookIn(); - break; - - case 4: - order(0); - break; - - case 5: - displayAll(); - break; - } - } - } - - private void displayItem() - { - try - { - int id = getMenu("\nStockID to display", item.getLastID()); - if (id > 0) - { - item.fetchItem(id); - System.out.println("========================================"); - - String status = ""; - if (!item.isItemValid()) - status = " ** Superceded **"; - - int av = item.getAvailable(); - - System.out.println(" Stock ID: " + id + status + - "\nItems Available: " + av + - "\nItems on order: " + item.getOrdered() + - "\n Description: " + item.getDescription()); - System.out.println("========================================"); - - if (av > 0) - if (yn("Take this item out of stock?")) - { - int rem = 1; - if (av > 1) - rem = getMenu("How many?", av); - if (rem > 0) - item.removeStock(rem); - } - - } - } - catch (Exception e) - { - System.out.println(e.toString()); - e.printStackTrace(); - } - } - - private void bookOut() - { - try - { - int id = getMenu("\nStockID to take out", item.getLastID()); - if (id > 0) - { - item.fetchItem(id); - int av = item.getAvailable(); - if (av > 0) - if (yn("Take this item out of stock?")) - { - int rem = 1; - if (av > 1) - rem = getMenu("How many?", av); - if (rem > 0) - item.removeStock(rem); - } - else - { - System.out.println("This item is not in stock."); - int order = item.getOrdered(); - if (order > 0) - System.out.println("There are " + item.getOrdered() + " items on order."); - else - { - if (item.isItemValid()) - { - System.out.println("You will need to order some more " + item.getDescription()); - order(id); - } - else - System.out.println("This item is now obsolete"); - } - } - } - else - System.out.println(item.getDescription() + "\nThis item is out of stock"); - } - catch (Exception e) - { - System.out.println(e.toString()); - e.printStackTrace(); - } - } - - // book an item into stock - private void bookIn() - { - try - { - int id = getMenu("\nStockID to book in", item.getLastID()); - item.fetchItem(id); - System.out.println(item.getDescription()); - - if (item.getOrdered() > 0) - { - int am = getMenu("How many do you want to book in", item.getOrdered()); - if (am > 0) - item.addNewStock(am); - } - else - System.out.println("You don't have any of this item on ordered"); - - } - catch (Exception e) - { - System.out.println(e.toString()); - e.printStackTrace(); - } - } - - // Order an item - private void order(int id) - { - try - { - if (id == 0) - id = getMenu("\nStockID to order", item.getLastID()); - item.fetchItem(id); - System.out.println(item.getDescription()); - int am = getMenu("How many do you want to order", 999); - if (am > 0) - item.orderStock(am); - } - catch (Exception e) - { - System.out.println(e.toString()); - e.printStackTrace(); - } - } - - private void displayAll() - { - try - { - boolean cont = true; - int nr = item.getLastID(); - String header = "\nId\tAvail\tOrdered\tDescription"; - System.out.println(header); - for (int i = 1;i <= nr && cont;i++) - { - item.fetchItem(i); - System.out.println("" + i + "\t" + item.getAvailable() + "\t" + item.getOrdered() + "\t" + item.getDescription()); - if ((i % 20) == 0) - { - if ((cont = yn("Continue?"))) - System.out.println(header); - } - } - } - catch (Exception e) - { - System.out.println(e.toString()); - e.printStackTrace(); - } - } - - private int getMenu(String title, int max) - { - int v = -1; - while (v < 0 || v > max) - { - System.out.print(title); - System.out.print(" [0-" + max + "]: "); - System.out.flush(); - try - { - v = Integer.parseInt(in.readLine()); - } - catch (Exception nfe) - { - v = -1; - } - } - return v; - } - - private boolean yn(String title) - { - try - { - while (true) - { - System.out.print(title); - System.out.flush(); - String s = in.readLine(); - if (s.startsWith("y") || s.startsWith("Y")) - return true; - if (s.startsWith("n") || s.startsWith("N")) - return false; - } - } - catch (Exception nfe) - { - System.out.println(nfe.toString()); - nfe.printStackTrace(); - System.exit(1); - } - return false; - } -} diff --git a/src/interfaces/jdbc/example/corba/StockDB.java b/src/interfaces/jdbc/example/corba/StockDB.java deleted file mode 100644 index 90fb8d28048..00000000000 --- a/src/interfaces/jdbc/example/corba/StockDB.java +++ /dev/null @@ -1,134 +0,0 @@ -package example.corba; - -import java.sql.*; - -/* - * This class handles the JDBC side of things. It opens a connection to - * the database, and performes queries on that database. - * - * In essence, you could use this class on it's own. The rest of the classes - * in this example handle either the CORBA mechanism, or the frontend. - * - * Note: Before you ask, why perform a query on each call, you have to remember - * that an object could be changed by another client, and we need to ensure that - * the returned data is live and accurate. - * - * $PostgreSQL: pgsql/src/interfaces/jdbc/example/corba/StockDB.java,v 1.5 2003/11/29 22:41:21 pgsql Exp $ - */ -public class StockDB -{ - Connection con; - Statement st; - - // the current stock number - int id = -1; - - public void connect(String url, String usr, String pwd) throws Exception - { - Class.forName("org.postgresql.Driver"); - System.out.println("Connecting to " + url); - con = DriverManager.getConnection(url, usr, pwd); - st = con.createStatement(); - } - - public void closeConnection() throws Exception - { - con.close(); - } - - public void fetchItem(int id) throws Exception - { - this.id = id; - } - - public int newItem() throws Exception - { - // tba - return -1; - } - - public String getDescription() throws SQLException - { - ResultSet rs = st.executeQuery("select description from stock where id=" + id); - if (rs != null) - { - rs.next(); - String s = rs.getString(1); - rs.close(); - return s; - } - throw new SQLException("No ResultSet"); - } - - public int getAvailable() throws SQLException - { - ResultSet rs = st.executeQuery("select avail from stock where id=" + id); - if (rs != null) - { - rs.next(); - int v = rs.getInt(1); - rs.close(); - return v; - } - throw new SQLException("No ResultSet"); - } - - public int getOrdered() throws SQLException - { - ResultSet rs = st.executeQuery("select ordered from stock where id=" + id); - if (rs != null) - { - rs.next(); - int v = rs.getInt(1); - rs.close(); - return v; - } - throw new SQLException("No ResultSet"); - } - - public boolean isItemValid() throws SQLException - { - ResultSet rs = st.executeQuery("select valid from stock where id=" + id); - if (rs != null) - { - rs.next(); - boolean b = rs.getBoolean(1); - rs.close(); - return b; - } - throw new SQLException("No ResultSet"); - } - - public void addNewStock(int amount) throws SQLException - { - st.executeUpdate("update stock set avail=avail+" + amount + - ", ordered=ordered-" + amount + - " where id=" + id + " and ordered>=" + amount); - } - - public void removeStock(int amount) throws SQLException - { - st.executeUpdate("update stock set avail=avail-" + amount + - " where id=" + id); - } - - public void orderStock(int amount) throws SQLException - { - st.executeUpdate("update stock set ordered=ordered+" + amount + - " where id=" + id); - } - - public int getLastID() throws SQLException - { - ResultSet rs = st.executeQuery("select max(id) from stock"); - if (rs != null) - { - rs.next(); - int v = rs.getInt(1); - rs.close(); - return v; - } - throw new SQLException("No ResultSet"); - } - -} diff --git a/src/interfaces/jdbc/example/corba/StockDispenserImpl.java b/src/interfaces/jdbc/example/corba/StockDispenserImpl.java deleted file mode 100644 index 132b58f64c0..00000000000 --- a/src/interfaces/jdbc/example/corba/StockDispenserImpl.java +++ /dev/null @@ -1,92 +0,0 @@ -package example.corba; - -import org.omg.CosNaming.*; - -/* - * This class implements the server side of the example. - * - * $PostgreSQL: pgsql/src/interfaces/jdbc/example/corba/StockDispenserImpl.java,v 1.6 2003/11/29 22:41:21 pgsql Exp $ - */ -public class StockDispenserImpl extends stock._StockDispenserImplBase -{ - private int maxObjects = 10; - private int numObjects = 0; - private StockItemStatus[] stock = new StockItemStatus[maxObjects]; - - public StockDispenserImpl(String[] args, String name, int num) - { - super(); - - try - { - // get reference to orb - org.omg.CORBA.ORB orb = org.omg.CORBA.ORB.init(args, null); - - // prestart num objects - if (num >= maxObjects) - num = maxObjects; - numObjects = num; - for (int i = 0;i < numObjects;i++) - { - stock[i] = new StockItemStatus(); - stock[i].ref = new StockItemImpl(args, "StockItem" + (i + 1)); - orb.connect(stock[i].ref); - } - } - catch (org.omg.CORBA.SystemException e) - { - e.printStackTrace(); - } - } - - /* - * This method, defined in stock.idl, reserves a slot in the dispenser - */ - public stock.StockItem reserveItem() throws stock.StockException - { - for (int i = 0;i < numObjects;i++) - { - if (!stock[i].inUse) - { - stock[i].inUse = true; - System.out.println("Reserving slot " + i); - return stock[i].ref; - } - } - return null; - } - - /* - * This releases a slot from the dispenser - */ - public void releaseItem(stock.StockItem item) throws stock.StockException - { - for (int i = 0;i < numObjects;i++) - { - if (stock[i].ref.getInstanceName().equals(item.getInstanceName())) - { - stock[i].inUse = false; - System.out.println("Releasing slot " + i); - return ; - } - } - System.out.println("Reserved object not a member of this dispenser"); - return ; - } - - /* - * This class defines a slot in the dispenser - */ - class StockItemStatus - { - StockItemImpl ref; - boolean inUse; - - StockItemStatus() - { - ref = null; - inUse = false; - } - } - -} diff --git a/src/interfaces/jdbc/example/corba/StockItemImpl.java b/src/interfaces/jdbc/example/corba/StockItemImpl.java deleted file mode 100644 index 4b52dc18056..00000000000 --- a/src/interfaces/jdbc/example/corba/StockItemImpl.java +++ /dev/null @@ -1,208 +0,0 @@ -package example.corba; - -import org.omg.CosNaming.*; - -/* - * This class implements the server side of the example. - * - * $PostgreSQL: pgsql/src/interfaces/jdbc/example/corba/StockItemImpl.java,v 1.4 2003/11/29 22:41:21 pgsql Exp $ - */ -public class StockItemImpl extends stock._StockItemImplBase -{ - private StockDB db; - private String instanceName; - - public StockItemImpl(String[] args, String iname) - { - super(); - try - { - db = new StockDB(); - db.connect(args[1], args[2], args[3]); - System.out.println("StockDB object " + iname + " created"); - instanceName = iname; - } - catch (Exception e) - { - e.printStackTrace(); - } - } - - /* - * This is defined in stock.idl - * - * It sets the item to view - */ - public void fetchItem(int id) throws stock.StockException - { - try - { - db.fetchItem(id); - } - catch (Exception e) - { - throw new stock.StockException(e.toString()); - } - } - - - /* - * This is defined in stock.idl - * - * It sets the item to view - */ - public int newItem() throws stock.StockException - { - try - { - return db.newItem(); - } - catch (Exception e) - { - throw new stock.StockException(e.toString()); - } - } - - /* - * This is defined in stock.idl - * - * It returns the description of a Stock item - */ - public String getDescription() throws stock.StockException - { - try - { - return db.getDescription(); - } - catch (Exception e) - { - throw new stock.StockException(e.toString()); - } - } - - /* - * This is defined in stock.idl - * - * It returns the description of a Stock item - */ - public int getAvailable() throws stock.StockException - { - try - { - return db.getAvailable(); - } - catch (Exception e) - { - throw new stock.StockException(e.toString()); - } - } - - /* - * This is defined in stock.idl - * - * It returns the description of a Stock item - */ - public int getOrdered() throws stock.StockException - { - try - { - return db.getOrdered(); - } - catch (Exception e) - { - throw new stock.StockException(e.toString()); - } - } - - /* - * This is defined in stock.idl - * - * It returns the description of a Stock item - */ - public boolean isItemValid() throws stock.StockException - { - try - { - return db.isItemValid(); - } - catch (Exception e) - { - throw new stock.StockException(e.toString()); - } - } - - /* - * This is defined in stock.idl - * - * It returns the description of a Stock item - */ - public void addNewStock(int id) throws stock.StockException - { - try - { - db.addNewStock(id); - } - catch (Exception e) - { - throw new stock.StockException(e.toString()); - } - } - - /* - * This is defined in stock.idl - * - * It returns the description of a Stock item - */ - public void removeStock(int id) throws stock.StockException - { - try - { - db.removeStock(id); - } - catch (Exception e) - { - throw new stock.StockException(e.toString()); - } - } - - /* - * This is defined in stock.idl - * - * It returns the description of a Stock item - */ - public void orderStock(int id) throws stock.StockException - { - try - { - db.orderStock(id); - } - catch (Exception e) - { - throw new stock.StockException(e.toString()); - } - } - - /* - * This returns the highest id used, hence the number of items available - */ - public int getLastID() throws stock.StockException - { - try - { - return db.getLastID(); - } - catch (Exception e) - { - throw new stock.StockException(e.toString()); - } - } - - /* - * This is used by our Dispenser - */ - public String getInstanceName() - { - return instanceName; - } -} - diff --git a/src/interfaces/jdbc/example/corba/StockServer.java b/src/interfaces/jdbc/example/corba/StockServer.java deleted file mode 100644 index 18c8b893faa..00000000000 --- a/src/interfaces/jdbc/example/corba/StockServer.java +++ /dev/null @@ -1,58 +0,0 @@ -package example.corba; - -import org.omg.CosNaming.*; - -/* - * This class implements the server side of the example. - * - * $PostgreSQL: pgsql/src/interfaces/jdbc/example/corba/StockServer.java,v 1.6 2003/11/29 22:41:21 pgsql Exp $ - */ -public class StockServer -{ - public static void main(String[] args) - { - int numInstances = 3; - - try - { - // Initialise the ORB - org.omg.CORBA.ORB orb = org.omg.CORBA.ORB.init(args, null); - - // Create the StockDispenser object - StockDispenserImpl dispenser = new StockDispenserImpl(args, "Stock Dispenser", numInstances); - - // Export the new object - orb.connect(dispenser); - - // Get the naming service - org.omg.CORBA.Object nameServiceObj = orb.resolve_initial_references("NameService"); - if (nameServiceObj == null) - { - System.err.println("nameServiceObj = null"); - return ; - } - - org.omg.CosNaming.NamingContext nameService = org.omg.CosNaming.NamingContextHelper.narrow(nameServiceObj); - if (nameService == null) - { - System.err.println("nameService = null"); - return ; - } - - // bind the dispenser into the naming service - NameComponent[] dispenserName = { - new NameComponent("StockDispenser", "Stock") - }; - nameService.rebind(dispenserName, dispenser); - - // Now wait forever for the current thread to die - Thread.currentThread().join(); - } - catch (Exception e) - { - e.printStackTrace(); - } - } -} - - diff --git a/src/interfaces/jdbc/example/corba/readme b/src/interfaces/jdbc/example/corba/readme deleted file mode 100644 index d44c17613f3..00000000000 --- a/src/interfaces/jdbc/example/corba/readme +++ /dev/null @@ -1,34 +0,0 @@ - -The CORBA example is the most complicated of the examples. It -aims to show how to use JDBC & Java2's ORB to access PostgreSQL. - -To compile: - -Type "make corba" to build the example. This will create a new directory -stock which contains the stubs needed by the orb, and all required classes -under the example/corba directory. - -To run: - -NOTE: To run, you will need 3 shells on Win32 (under unix you can get away -with two shells): - -1: Start the naming service - -Unix: tnameserv -ORBInitialPort 1050 & -Win32: tnameserv -ORBInitialPort 1050 - -2: Start the StockServer - - java example.corba.StockServer 3 jdbc:postgresql:dbase user passwd -ORBInitialPort 1050 - -Where: - 3 Number of concurrent sessions to allow - dbase The database (including a hostname if required) - user The PostgreSQL user name - passwd The password - -3: Using a fresh shell, run the client: - - java example.corba.StockClient -ORBInitialPort 1050 - diff --git a/src/interfaces/jdbc/example/corba/stock.idl b/src/interfaces/jdbc/example/corba/stock.idl deleted file mode 100755 index 4be5a79d7d2..00000000000 --- a/src/interfaces/jdbc/example/corba/stock.idl +++ /dev/null @@ -1,40 +0,0 @@ -// $PostgreSQL: pgsql/src/interfaces/jdbc/example/corba/stock.idl,v 1.2 2003/11/29 22:41:21 pgsql Exp $ -// -// This is our CORBA bindings for a very simple stock control -// system. -// -// $PostgreSQL: pgsql/src/interfaces/jdbc/example/corba/stock.idl,v 1.2 2003/11/29 22:41:21 pgsql Exp $ -// - -// For some reason, idltojava on my setup doesn't like this to be -// in caps. It could be a problem with Win95 & Samba, but for now, -// this is in lowercase -module stock -{ - exception StockException - { - string reason; - }; - - interface StockItem - { - void fetchItem(in long id) raises (StockException); - long newItem() raises (StockException); - string getDescription() raises (StockException); - long getAvailable() raises (StockException); - long getOrdered() raises (StockException); - boolean isItemValid() raises (StockException); - void addNewStock(in long amount) raises (StockException); - void removeStock(in long amount) raises (StockException); - void orderStock(in long amount) raises (StockException); - long getLastID() raises (StockException); - string getInstanceName(); - }; - - interface StockDispenser - { - StockItem reserveItem() raises (StockException); - void releaseItem(in StockItem item) raises (StockException); - }; - -}; diff --git a/src/interfaces/jdbc/example/corba/stock.sql b/src/interfaces/jdbc/example/corba/stock.sql deleted file mode 100644 index 6082ad6fe1e..00000000000 --- a/src/interfaces/jdbc/example/corba/stock.sql +++ /dev/null @@ -1,27 +0,0 @@ --- --- This creates the database for the stock example --- $PostgreSQL: pgsql/src/interfaces/jdbc/example/corba/stock.sql,v 1.2 2003/11/29 22:41:21 pgsql Exp $ --- -drop table stock; - -create table stock ( - id int4, - avail int4, - ordered int4, - valid bool, - description text -); - -create index stock_id on stock(id); - -copy stock from stdin; -1 19 0 t Dell Latitude XPi P133 Laptop -2 3 2 t Iomega Zip Plus drive -3 2 0 f Iomega Ext/Par drive -4 0 4 t Iomega Ext USB drive -5 200 0 t Blank Unbranded CDR media -6 20 30 t Iomega Zip media 100Mb -\. - -grant all on stock to public; -grant all on stock_id to public; diff --git a/src/interfaces/jdbc/example/datestyle.java b/src/interfaces/jdbc/example/datestyle.java deleted file mode 100644 index 26a14a760bb..00000000000 --- a/src/interfaces/jdbc/example/datestyle.java +++ /dev/null @@ -1,186 +0,0 @@ -package example; - -import java.io.*; -import java.sql.*; - -/* - * This example tests the various date styles that are available to postgresql. - * - * To use this example, you need a database to be in existence. This example - * will create a table called datestyle. - */ - -public class datestyle -{ - Connection db; // The connection to the database - Statement st; // Our statement to run queries with - - // This is our standard to compare results with. - java.sql.Date standard; - - // This is a list of the available date styles including variants. - // These have to match what the "set datestyle" statement accepts. - String styles[] = { - "postgres,european", - "postgres,us", - "iso", // iso has no variants - us/european has no affect - "sql,european", - "sql,us", - "german" // german has no variants - us/european has no affect - }; - - public datestyle(String args[]) throws ClassNotFoundException, FileNotFoundException, IOException, SQLException - { - String url = args[0]; - String usr = args[1]; - String pwd = args[2]; - - // Load the driver - Class.forName("org.postgresql.Driver"); - - // Connect to database - System.out.println("Connecting to Database URL = " + url); - db = DriverManager.getConnection(url, usr, pwd); - - System.out.println("Connected...Now creating a statement"); - st = db.createStatement(); - - // Clean up the database (in case we failed earlier) then initialise - cleanup(); - init(); - - // Now run tests using JDBC methods - doexample(); - - // Clean up the database - cleanup(); - - // Finally close the database - System.out.println("Now closing the connection"); - st.close(); - db.close(); - - } - - /* - * This drops the table (if it existed). No errors are reported. - */ - public void cleanup() - { - try - { - st.executeUpdate("drop table datestyle"); - } - catch (Exception ex) - { - // We ignore any errors here - } - } - - /* - * This initialises the database for this example - */ - public void init() throws SQLException - { - // Create a table holding a single date - st.executeUpdate("create table datestyle (dt date)"); - - // Now create our standard date for the test. - // - // NB: each component of the date should be different, otherwise the tests - // will not be valid. - // - // NB: January = 0 here - // - standard = new java.sql.Date(98, 0, 8); - - // Now store the result. - // - // This is an example of how to set a date in a date style independent way. - // The only way of doing this is by using a PreparedStatement. - // - PreparedStatement ps = db.prepareStatement("insert into datestyle values (?)"); - ps.setDate(1, standard); - ps.executeUpdate(); - ps.close(); - } - - /* - * This performs the example - */ - public void doexample() throws SQLException - { - System.out.println("\nRunning tests:"); - - for (int i = 0;i < styles.length;i++) - { - System.out.print("Test " + i + " - " + styles[i]); - System.out.flush(); - - // set the style - st.executeUpdate("set datestyle='" + styles[i] + "'"); - - // Now because the driver needs to know what the current style is, - // we have to run the following: - st.executeUpdate("show datestyle"); - // This is a limitation, but there is no real way around this. - - // Now we query the table. - ResultSet rs = st.executeQuery("select dt from datestyle"); - - // Throw an exception if there is no result (if the table is empty - // there should still be a result). - if (rs == null) - throw new SQLException("The test query returned no data"); - - while (rs.next()) - { - // The JDBC spec states we should only read each column once. - // In the current implementation of the driver, this is not necessary. - // Here we use this fact to see what the query really returned. - if (standard.equals(rs.getDate(1))) - System.out.println(" passed, returned " + rs.getString(1)); - else - System.out.println(" failed, returned " + rs.getString(1)); - } - rs.close(); - } - } - - /* - * Display some instructions on how to run the example - */ - public static void instructions() - { - System.out.println("\nThis example tests the drivers ability to handle dates correctly if the\nbackend is running any of the various date styles that it supports.\nIdealy this should work fine. If it doesn't, then there is something wrong\npossibly in postgresql.Connection or in the backend itself. If this does occur\nthen please email a bug report.\n"); - System.out.println("Useage:\n java example.datestyle jdbc:postgresql:database user password [debug]\n\nThe debug field can be anything. It's presence will enable DriverManager's\ndebug trace. Unless you want to see screens of items, don't put anything in\nhere."); - System.exit(1); - } - - /* - * This little lot starts the test - */ - public static void main(String args[]) - { - System.out.println("PostgreSQL datestyle test v6.3 rev 1\n"); - - if (args.length < 3) - instructions(); - - // This line outputs debug information to stderr. To enable this, simply - // add an extra parameter to the command line - if (args.length > 3) - DriverManager.setLogStream(System.err); - - // Now run the tests - try - { - datestyle test = new datestyle(args); - } - catch (Exception ex) - { - System.err.println("Exception caught.\n" + ex); - ex.printStackTrace(); - } - } -} diff --git a/src/interfaces/jdbc/example/metadata.java b/src/interfaces/jdbc/example/metadata.java deleted file mode 100644 index b796329923a..00000000000 --- a/src/interfaces/jdbc/example/metadata.java +++ /dev/null @@ -1,296 +0,0 @@ -package example; - -import java.io.*; -import java.sql.*; - -/* - * This example application is not really an example. It actually performs - * some tests on various methods in the DatabaseMetaData and ResultSetMetaData - * classes. - * - * To use it, simply have a database created. It will create some work tables - * and run tests on them. - */ - -public class metadata -{ - Connection db; // The connection to the database - Statement st; // Our statement to run queries with - DatabaseMetaData dbmd; // This defines the structure of the database - - /* - * These are the available tests on DatabaseMetaData - */ - public void doDatabaseMetaData() throws SQLException - { - if (doTest("getProcedures() - should show all available procedures")) - displayResult(dbmd.getProcedures(null, null, null)); - - if (doTest("getProcedures() with pattern - should show all circle procedures")) - displayResult(dbmd.getProcedures(null, null, "circle%")); - - if (doTest("getProcedureColumns() on circle procedures")) - displayResult(dbmd.getProcedureColumns(null, null, "circle%", null)); - - if (doTest("getTables()")) - displayResult(dbmd.getTables(null, null, null, null)); - - if (doTest("getColumns() - should show all tables, can take a while to run")) - displayResult(dbmd.getColumns(null, null, null, null)); - - if (doTest("getColumns() - should show the test_b table")) - displayResult(dbmd.getColumns(null, null, "test_b", null)); - - if (doTest("getColumnPrivileges() - should show all tables")) - displayResult(dbmd.getColumnPrivileges(null, null, null, null)); - - if (doTest("getPrimaryKeys()")) - displayResult(dbmd.getPrimaryKeys(null, null, null)); - - if (doTest("getTypeInfo()")) - displayResult(dbmd.getTypeInfo()); - - } - - /* - * These are the available tests on ResultSetMetaData - */ - public void doResultSetMetaData() throws SQLException - { - - String sql = "select imagename,descr,source,cost from test_a,test_b,test_c where test_a.id=test_b.imageid and test_a.id=test_c.imageid"; - - System.out.println("Executing query for tests"); - ResultSet rs = st.executeQuery(sql); - ResultSetMetaData rsmd = rs.getMetaData(); - - if (doTest("isCurrency()")) - System.out.println("isCurrency on col 1 = " + rsmd.isCurrency(1) + " should be false\nisCurrency on col 4 = " + rsmd.isCurrency(4) + " should be true"); - - // Finally close the query. Now give the user a chance to display the - // ResultSet. - // - // NB: displayResult() actually closes the ResultSet. - if (doTest("Display query result")) - { - System.out.println("Query: " + sql); - displayResult(rs); - } - else - rs.close(); - } - - /* - * This creates some test data - */ - public void init() throws SQLException - { - System.out.println("Creating some tables"); - cleanup(); - st.executeUpdate("create table test_a (imagename name,image oid,id int4)"); - st.executeUpdate("create table test_b (descr text,imageid int4,id int4)"); - st.executeUpdate("create table test_c (source text,cost money,imageid int4)"); - - System.out.println("Adding some data"); - st.executeUpdate("insert into test_a values ('test1',0,1)"); - st.executeUpdate("insert into test_b values ('A test description',1,2)"); - st.executeUpdate("insert into test_c values ('nowhere particular','$10.99',1)"); - } - - /* - * This removes the test data - */ - public void cleanup() throws SQLException - { - try - { - st.executeUpdate("drop table test_a"); - st.executeUpdate("drop table test_b"); - st.executeUpdate("drop table test_c"); - } - catch (Exception ex) - { - // We ignore any errors here - } - } - - public metadata(String args[]) throws ClassNotFoundException, FileNotFoundException, IOException, SQLException - { - String url = args[0]; - String usr = args[1]; - String pwd = args[2]; - - // Load the driver - Class.forName("org.postgresql.Driver"); - - // Connect to database - System.out.println("Connecting to Database URL = " + url); - db = DriverManager.getConnection(url, usr, pwd); - - dbmd = db.getMetaData(); - st = db.createStatement(); - - // This prints the backend's version - System.out.println("Connected to " + dbmd.getDatabaseProductName() + " " + dbmd.getDatabaseProductVersion()); - - init(); - - System.out.println(); - - // Now the tests - if (doTest("Test DatabaseMetaData")) - doDatabaseMetaData(); - - if (doTest("Test ResultSetMetaData")) - doResultSetMetaData(); - - System.out.println("\nNow closing the connection"); - st.close(); - db.close(); - - cleanup(); - } - - /* - * This asks if the user requires to run a test. - */ - public boolean doTest(String s) - { - System.out.println(); - System.out.print(s); - System.out.print(" Perform test? Y or N:"); - System.out.flush(); - char c = ' '; - try - { - while (!(c == 'n' || c == 'y' || c == 'N' || c == 'Y')) - { - c = (char)System.in.read(); - } - } - catch (IOException ioe) - { - return false; - } - - return c == 'y' || c == 'Y'; - } - - /* - * This displays a result set. - * Note: it closes the result once complete. - */ - public void displayResult(ResultSet rs) throws SQLException - { - ResultSetMetaData rsmd = rs.getMetaData(); - int count = 0; - - // Print the result column names - int cols = rsmd.getColumnCount(); - for (int i = 1;i <= cols;i++) - System.out.print(rsmd.getColumnLabel(i) + (i < cols ? "\t" : "\n")); - - // now the results - while (rs.next()) - { - count++; - for (int i = 1;i <= cols;i++) - { - Object o = rs.getObject(i); - if (rs.wasNull()) - System.out.print("{null}" + (i < cols ? "\t" : "\n")); - else - System.out.print(o.toString() + (i < cols ? "\t" : "\n")); - } - } - - System.out.println("Result returned " + count + " rows."); - - // finally close the result set - rs.close(); - } - - /* - * This process / commands (for now just /d) - */ - public void processSlashCommand(String line) throws SQLException - { - if (line.startsWith("\\d")) - { - if (line.startsWith("\\d ")) - { - // Display details about a table - String table = line.substring(3); - displayResult(dbmd.getColumns(null, null, table, "%")); - } - else - { - String types[] = null; - if (line.equals("\\d")) - types = allUserTables; - else if (line.equals("\\di")) - types = usrIndices; - else if (line.equals("\\dt")) - types = usrTables; - else if (line.equals("\\ds")) - types = usrSequences; - else if (line.equals("\\dS")) - types = sysTables; - else - throw new SQLException("Unsupported \\d command: " + line); - - // Display details about all system tables - // - // Note: the first two arguments are ignored. To keep to the spec, - // you must put null here - // - displayResult(dbmd.getTables(null, null, "%", types)); - } - } - else - throw new SQLException("Unsupported \\ command: " + line); - } - - private static final String allUserTables[] = {"TABLE", "INDEX", "SEQUENCE"}; - private static final String usrIndices[] = {"INDEX"}; - private static final String usrTables[] = {"TABLE"}; - private static final String usrSequences[] = {"SEQUENCE"}; - private static final String sysTables[] = {"SYSTEM TABLE", "SYSTEM INDEX"}; - - /* - * Display some instructions on how to run the example - */ - public static void instructions() - { - System.out.println("\nThis is not really an example, but is used to test the various methods in\nthe DatabaseMetaData and ResultSetMetaData classes.\n"); - System.out.println("Useage:\n java example.metadata jdbc:postgresql:database user password [debug]\n\nThe debug field can be anything. It's presence will enable DriverManager's\ndebug trace. Unless you want to see screens of debug items, don't put anything in\nhere."); - System.exit(1); - } - - /* - * This little lot starts the test - */ - public static void main(String args[]) - { - System.out.println("PostgreSQL metdata tester v6.4 rev 1\n"); - - if (args.length < 3) - instructions(); - - // This line outputs debug information to stderr. To enable this, simply - // add an extra parameter to the command line - if (args.length > 3) - DriverManager.setLogStream(System.err); - - // Now run the tests - try - { - metadata test = new metadata(args); - } - catch (Exception ex) - { - System.err.println("Exception caught.\n" + ex); - ex.printStackTrace(); - } - } -} diff --git a/src/interfaces/jdbc/example/psql.java b/src/interfaces/jdbc/example/psql.java deleted file mode 100644 index 283739acd72..00000000000 --- a/src/interfaces/jdbc/example/psql.java +++ /dev/null @@ -1,234 +0,0 @@ -package example; - -import java.io.*; -import java.sql.*; - -/* - * This example application demonstrates some of the drivers other features - * by implementing a simple psql replacement in Java. - * - */ - -public class psql -{ - Connection db; // The connection to the database - Statement st; // Our statement to run queries with - DatabaseMetaData dbmd; // This defines the structure of the database - boolean done = false; // Added by CWJ to permit \q command - - public psql(String args[]) throws ClassNotFoundException, FileNotFoundException, IOException, SQLException - { - String url = args[0]; - String usr = args[1]; - String pwd = args[2]; - - // Load the driver - Class.forName("org.postgresql.Driver"); - - // Connect to database - System.out.println("Connecting to Database URL = " + url); - db = DriverManager.getConnection(url, usr, pwd); - - dbmd = db.getMetaData(); - st = db.createStatement(); - - // This prints the backend's version - System.out.println("Connected to " + dbmd.getDatabaseProductName() + " " + dbmd.getDatabaseProductVersion()); - - System.out.println(); - - // This provides us the means of reading from stdin - StreamTokenizer input = new StreamTokenizer(new InputStreamReader(System.in)); - input.resetSyntax(); - input.slashSlashComments(true); // allow // as a comment delimiter - input.eolIsSignificant(false); // treat eol's as spaces - input.wordChars(32, 126); - input.whitespaceChars(59, 59); - // input.quoteChar(39); *** CWJ: messes up literals in query string *** - - // Now the main loop. - int tt = 0, lineno = 1; - while (tt != StreamTokenizer.TT_EOF && ! done) - { - System.out.print("[" + lineno + "] "); - System.out.flush(); - - // Here, we trap SQLException so they don't terminate the application - try - { - if ((tt = input.nextToken()) == StreamTokenizer.TT_WORD) - { - processLine(input.sval); - lineno++; - } - } - catch (SQLException ex) - { - System.out.println(ex.getMessage()); - } - } - - System.out.println("Now closing the connection"); - st.close(); - db.close(); - } - - /* - * This processes a statement - */ - public void processLine(String line) throws SQLException - { - if (line.startsWith("\\")) - { - processSlashCommand(line); - return ; - } - - boolean type = st.execute(line); - boolean loop = true; - while (loop) - { - if (type) - { - // A ResultSet was returned - ResultSet rs = st.getResultSet(); - displayResult(rs); - } - else - { - int count = st.getUpdateCount(); - - if (count == -1) - { - // This indicates nothing left - loop = false; - } - else - { - // An update count was returned - System.out.println("Updated " + st.getUpdateCount() + " rows"); - } - } - - if (loop) - type = st.getMoreResults(); - } - } - - /* - * This displays a result set. - * Note: it closes the result once complete. - */ - public void displayResult(ResultSet rs) throws SQLException - { - ResultSetMetaData rsmd = rs.getMetaData(); - - // Print the result column names - int cols = rsmd.getColumnCount(); - for (int i = 1;i <= cols;i++) - System.out.print(rsmd.getColumnLabel(i) + (i < cols ? "\t" : "\n")); - - // now the results - while (rs.next()) - { - for (int i = 1;i <= cols;i++) - { - Object o = rs.getObject(i); - if (rs.wasNull()) - System.out.print("{null}" + (i < cols ? "\t" : "\n")); - else - System.out.print(o.toString() + (i < cols ? "\t" : "\n")); - } - } - - // finally close the result set - rs.close(); - } - - /* - * This process / commands (for now just /d) - */ - public void processSlashCommand(String line) throws SQLException - { - if (line.startsWith("\\d")) - { - - if (line.startsWith("\\d ")) - { - // Display details about a table - String table = line.substring(3); - displayResult(dbmd.getColumns(null, null, table, "%")); - } - else - { - String types[] = null; - if (line.equals("\\d")) - types = allUserTables; - else if (line.equals("\\di")) - types = usrIndices; - else if (line.equals("\\dt")) - types = usrTables; - else if (line.equals("\\ds")) - types = usrSequences; - else if (line.equals("\\dS")) - types = sysTables; - else - throw new SQLException("Unsupported \\d command: " + line); - - // Display details about all system tables - // - // Note: the first two arguments are ignored. To keep to the spec, - // you must put null here - // - displayResult(dbmd.getTables(null, null, "%", types)); - } - } - else if (line.equals("\\q")) // Added by CWJ to permit \q command - done = true; - else - throw new SQLException("Unsupported \\ command: " + line); - } - - private static final String allUserTables[] = {"TABLE", "INDEX", "SEQUENCE"}; - private static final String usrIndices[] = {"INDEX"}; - private static final String usrTables[] = {"TABLE"}; - private static final String usrSequences[] = {"SEQUENCE"}; - private static final String sysTables[] = {"SYSTEM TABLE", "SYSTEM INDEX"}; - - /* - * Display some instructions on how to run the example - */ - public static void instructions() - { - System.out.println("\nThis example shows how some of the other JDBC features work within the\ndriver. It does this by implementing a very simple psql equivalent in java.\nNot everything that psql does is implemented.\n"); - System.out.println("Useage:\n java example.psql jdbc:postgresql:database user password [debug]\n\nThe debug field can be anything. It's presence will enable DriverManager's\ndebug trace. Unless you want to see screens of items, don't put anything in\nhere."); - System.exit(1); - } - - /* - * This little lot starts the test - */ - public static void main(String args[]) - { - System.out.println("PostgreSQL psql example v6.3 rev 1\n"); - - if (args.length < 3) - instructions(); - - // This line outputs debug information to stderr. To enable this, simply - // add an extra parameter to the command line - if (args.length > 3) - DriverManager.setLogStream(System.err); - - // Now run the tests - try - { - psql test = new psql(args); - } - catch (Exception ex) - { - System.err.println("Exception caught.\n" + ex); - ex.printStackTrace(); - } - } -} diff --git a/src/interfaces/jdbc/example/threadsafe.java b/src/interfaces/jdbc/example/threadsafe.java deleted file mode 100644 index cb6c0d03f2f..00000000000 --- a/src/interfaces/jdbc/example/threadsafe.java +++ /dev/null @@ -1,402 +0,0 @@ -package example; - -import java.io.*; -import java.sql.*; - -// rare in user code, but we use the LargeObject API in this test -import org.postgresql.largeobject.*; - -/* - * This example tests the thread safety of the driver. - * - * It does this by performing several queries, in different threads. Each - * thread has it's own Statement object, which is (in my understanding of the - * jdbc specification) the minimum requirement. - * - */ - -public class threadsafe -{ - Connection db; // The connection to the database - Statement st; // Our statement to run queries with - - public threadsafe(String args[]) throws ClassNotFoundException, FileNotFoundException, IOException, SQLException - { - String url = args[0]; - String usr = args[1]; - String pwd = args[2]; - - // Load the driver - Class.forName("org.postgresql.Driver"); - - // Connect to database - System.out.println("Connecting to Database URL = " + url); - db = DriverManager.getConnection(url, usr, pwd); - - System.out.println("Connected...Now creating a statement"); - st = db.createStatement(); - - // Clean up the database (in case we failed earlier) then initialise - cleanup(); - - // Because we use LargeObjects, we must use Transactions - db.setAutoCommit(false); - - // Now run tests using JDBC methods, then LargeObjects - doexample(); - - // Clean up the database - cleanup(); - - // Finally close the database - System.out.println("Now closing the connection"); - st.close(); - db.close(); - } - - /* - * This drops the table (if it existed). No errors are reported. - */ - public void cleanup() - { - try - { - st.executeUpdate("drop table basic1"); - } - catch (Exception ex) - { - // We ignore any errors here - } - - try - { - st.executeUpdate("drop table basic2"); - } - catch (Exception ex) - { - // We ignore any errors here - } - } - - /* - * This performs the example - */ - public void doexample() throws SQLException - { - System.out.println("\nThis test runs three Threads. Two simply insert data into a table, then\nthey perform a query. While they are running, a third thread is running,\nand it load data into, then reads from a Large Object.\n\nIf alls well, this should run without any errors. If so, we are Thread Safe.\nWhy test JDBC & LargeObject's? Because both will run over the network\nconnection, and if locking on the stream isn't done correctly, the backend\nwill get pretty confused!\n"); - - thread3 thread3 = null; - - try - { - - // create the two threads - Thread thread0 = Thread.currentThread(); - Thread thread1 = new thread1(db); - Thread thread2 = new thread2(db); - thread3 = new thread3(db); - - // now run, and wait for them - thread1.start(); - thread2.start(); - thread3.start(); - - // ok, I know this is bad, but it does the trick here as our main thread - // will yield as long as either of the children are still running - System.out.println("Waiting for threads to run"); - while (thread1.isAlive() || thread2.isAlive() || thread3.isAlive()) - Thread.yield(); - } - finally - { - // clean up after thread3 (the finally ensures this is run even - // if an exception is thrown inside the try { } construct) - if (thread3 != null) - thread3.cleanup(); - } - - System.out.println("No Exceptions have been thrown. This is a good omen, as it means that we are\npretty much thread safe as we can get."); - } - - // This is the first thread. It's the same as the basic test - class thread1 extends Thread - { - Connection c; - Statement st; - - public thread1(Connection c) throws SQLException - { - this.c = c; - st = c.createStatement(); - } - - public void run() - { - try - { - System.out.println("Thread 1 running..."); - - // First we need a table to store data in - st.executeUpdate("create table basic1 (a int2, b int2)"); - - // Now insert some data, using the Statement - st.executeUpdate("insert into basic1 values (1,1)"); - st.executeUpdate("insert into basic1 values (2,1)"); - st.executeUpdate("insert into basic1 values (3,1)"); - - // For large inserts, a PreparedStatement is more efficient, because it - // supports the idea of precompiling the SQL statement, and to store - // directly, a Java object into any column. PostgreSQL doesnt support - // precompiling, but does support setting a column to the value of a - // Java object (like Date, String, etc). - // - // Also, this is the only way of writing dates in a datestyle independent - // manner. (DateStyles are PostgreSQL's way of handling different methods - // of representing dates in the Date data type.) - PreparedStatement ps = db.prepareStatement("insert into basic1 values (?,?)"); - for (int i = 2;i < 2000;i++) - { - ps.setInt(1, 4); // "column a" = 5 - ps.setInt(2, i); // "column b" = i - ps.executeUpdate(); // executeUpdate because insert returns no data - // c.commit(); - if ((i % 50) == 0) - DriverManager.println("Thread 1 done " + i + " inserts"); - } - ps.close(); // Always close when we are done with it - - // Finally perform a query on the table - DriverManager.println("Thread 1 performing a query"); - ResultSet rs = st.executeQuery("select a, b from basic1"); - int cnt = 0; - if (rs != null) - { - // Now we run through the result set, printing out the result. - // Note, we must call .next() before attempting to read any results - while (rs.next()) - { - int a = rs.getInt("a"); // This shows how to get the value by name - int b = rs.getInt(2); // This shows how to get the value by column - //System.out.println(" a="+a+" b="+b); - cnt++; - } - rs.close(); // again, you must close the result when done - } - DriverManager.println("Thread 1 read " + cnt + " rows"); - - // The last thing to do is to drop the table. This is done in the - // cleanup() method. - System.out.println("Thread 1 finished"); - } - catch (SQLException se) - { - System.err.println("Thread 1: " + se.toString()); - se.printStackTrace(); - System.exit(1); - } - } - } - - // This is the second thread. It's the similar to the basic test, and thread1 - // except it works on another table. - class thread2 extends Thread - { - Connection c; - Statement st; - - public thread2(Connection c) throws SQLException - { - this.c = c; - st = c.createStatement(); - } - - public void run() - { - try - { - System.out.println("Thread 2 running..."); - - // First we need a table to store data in - st.executeUpdate("create table basic2 (a int2, b int2)"); - - // For large inserts, a PreparedStatement is more efficient, because it - // supports the idea of precompiling the SQL statement, and to store - // directly, a Java object into any column. PostgreSQL doesnt support - // precompiling, but does support setting a column to the value of a - // Java object (like Date, String, etc). - // - // Also, this is the only way of writing dates in a datestyle independent - // manner. (DateStyles are PostgreSQL's way of handling different methods - // of representing dates in the Date data type.) - PreparedStatement ps = db.prepareStatement("insert into basic2 values (?,?)"); - for (int i = 2;i < 2000;i++) - { - ps.setInt(1, 4); // "column a" = 5 - ps.setInt(2, i); // "column b" = i - ps.executeUpdate(); // executeUpdate because insert returns no data - // c.commit(); - if ((i % 50) == 0) - DriverManager.println("Thread 2 done " + i + " inserts"); - } - ps.close(); // Always close when we are done with it - - // Finally perform a query on the table - DriverManager.println("Thread 2 performing a query"); - ResultSet rs = st.executeQuery("select * from basic2 where b>1"); - int cnt = 0; - if (rs != null) - { - // First find out the column numbers. - // - // It's best to do this here, as calling the methods with the column - // numbers actually performs this call each time they are called. This - // really speeds things up on large queries. - // - int col_a = rs.findColumn("a"); - int col_b = rs.findColumn("b"); - - // Now we run through the result set, printing out the result. - // Again, we must call .next() before attempting to read any results - while (rs.next()) - { - int a = rs.getInt(col_a); // This shows how to get the value by name - int b = rs.getInt(col_b); // This shows how to get the value by column - //System.out.println(" a="+a+" b="+b); - cnt++; - } - rs.close(); // again, you must close the result when done - } - DriverManager.println("Thread 2 read " + cnt + " rows"); - - // The last thing to do is to drop the table. This is done in the - // cleanup() method. - System.out.println("Thread 2 finished"); - } - catch (SQLException se) - { - System.err.println("Thread 2: " + se.toString()); - se.printStackTrace(); - System.exit(1); - } - } - } - - // This is the third thread. It loads, then reads from a LargeObject, using - // our LargeObject api. - // - // The purpose of this is to test that FastPath will work in between normal - // JDBC queries. - class thread3 extends Thread - { - Connection c; - Statement st; - LargeObjectManager lom; - LargeObject lo; - int oid; - - public thread3(Connection c) throws SQLException - { - this.c = c; - //st = c.createStatement(); - - // create a blob - lom = ((org.postgresql.PGConnection)c).getLargeObjectAPI(); - oid = lom.create(); - System.out.println("Thread 3 has created a blob of oid " + oid); - } - - public void run() - { - try - { - System.out.println("Thread 3 running..."); - - DriverManager.println("Thread 3: Loading data into blob " + oid); - lo = lom.open(oid); - FileInputStream fis = new FileInputStream("example/threadsafe.java"); - // keep the buffer size small, to allow the other thread a chance - byte buf[] = new byte[128]; - int rc, bc = 1, bs = 0; - while ((rc = fis.read(buf)) > 0) - { - DriverManager.println("Thread 3 read block " + bc + " " + bs + " bytes"); - lo.write(buf, 0, rc); - bc++; - bs += rc; - } - lo.close(); - fis.close(); - - DriverManager.println("Thread 3: Reading blob " + oid); - lo = lom.open(oid); - bc = 0; - while (buf.length > 0) - { - buf = lo.read(buf.length); - if (buf.length > 0) - { - String s = new String(buf); - bc++; - DriverManager.println("Thread 3 block " + bc); - DriverManager.println("Block " + bc + " got " + s); - } - } - lo.close(); - - System.out.println("Thread 3 finished"); - } - catch (Exception se) - { - System.err.println("Thread 3: " + se.toString()); - se.printStackTrace(); - System.exit(1); - } - } - - public void cleanup() throws SQLException - { - if (lom != null && oid != 0) - { - System.out.println("Thread 3: Removing blob oid=" + oid); - lom.delete(oid); - } - } - } - - /* - * Display some instructions on how to run the example - */ - public static void instructions() - { - System.out.println("\nThis tests the thread safety of the driver.\n\nThis is done in two parts, the first with standard JDBC calls, and the\nsecond mixing FastPath and LargeObject calls with queries.\n"); - System.out.println("Useage:\n java example.threadsafe jdbc:postgresql:database user password [debug]\n\nThe debug field can be anything. It's presence will enable DriverManager's\ndebug trace. Unless you want to see screens of items, don't put anything in\nhere."); - System.exit(1); - } - - /* - * This little lot starts the test - */ - public static void main(String args[]) - { - System.out.println("PostgreSQL Thread Safety test v6.4 rev 1\n"); - - if (args.length < 3) - instructions(); - - // This line outputs debug information to stderr. To enable this, simply - // add an extra parameter to the command line - if (args.length > 3) - DriverManager.setLogStream(System.err); - - // Now run the tests - try - { - threadsafe test = new threadsafe(args); - } - catch (Exception ex) - { - System.err.println("Exception caught.\n" + ex); - ex.printStackTrace(); - } - } -} diff --git a/src/interfaces/jdbc/org/postgresql/Driver.java.in b/src/interfaces/jdbc/org/postgresql/Driver.java.in deleted file mode 100644 index 2e95bb748c8..00000000000 --- a/src/interfaces/jdbc/org/postgresql/Driver.java.in +++ /dev/null @@ -1,503 +0,0 @@ -/*------------------------------------------------------------------------- - * - * Driver.java(.in) - * The Postgresql JDBC Driver implementation - * - * Copyright (c) 2003, PostgreSQL Global Development Group - * - * IDENTIFICATION - * $PostgreSQL: pgsql/src/interfaces/jdbc/org/postgresql/Driver.java.in,v 1.40 2003/12/11 18:10:40 davec Exp $ - * - *------------------------------------------------------------------------- - */ -package org.postgresql; - -import java.io.*; -import java.sql.*; -import java.util.*; - -import org.postgresql.util.PSQLException; -import org.postgresql.util.PSQLState; - -/* - * The Java SQL framework allows for multiple database drivers. Each - * driver should supply a class that implements the Driver interface - * - * <p>The DriverManager will try to load as many drivers as it can find and - * then for any given connection request, it will ask each driver in turn - * to try to connect to the target URL. - * - * <p>It is strongly recommended that each Driver class should be small and - * standalone so that the Driver class can be loaded and queried without - * bringing in vast quantities of supporting code. - * - * <p>When a Driver class is loaded, it should create an instance of itself - * and register it with the DriverManager. This means that a user can load - * and register a driver by doing Class.forName("foo.bah.Driver") - * - * @see org.postgresql.PGConnection - * @see java.sql.Driver - */ -public class Driver implements java.sql.Driver -{ - - // make these public so they can be used in setLogLevel below - - public static final int DEBUG = 2; - public static final int INFO = 1; - public static boolean logDebug = false; - public static boolean logInfo = false; - - static - { - try - { - // moved the registerDriver from the constructor to here - // because some clients call the driver themselves (I know, as - // my early jdbc work did - and that was based on other examples). - // Placing it here, means that the driver is registered once only. - java.sql.DriverManager.registerDriver(new Driver()); - } - catch (SQLException e) - { - e.printStackTrace(); - } - } - - /* - * Try to make a database connection to the given URL. The driver - * should return "null" if it realizes it is the wrong kind of - * driver to connect to the given URL. This will be common, as - * when the JDBC driverManager is asked to connect to a given URL, - * it passes the URL to each loaded driver in turn. - * - * <p>The driver should raise an SQLException if it is the right driver - * to connect to the given URL, but has trouble connecting to the - * database. - * - * <p>The java.util.Properties argument can be used to pass arbitrary - * string tag/value pairs as connection arguments. - * - * user - (optional) The user to connect as - * password - (optional) The password for the user - * ssl - (optional) Use SSL when connecting to the server - * charSet - (optional) The character set to be used for converting - * to/from the database to unicode. If multibyte is enabled on the - * server then the character set of the database is used as the default, - * otherwise the jvm character encoding is used as the default. - * This value is only used when connecting to a 7.2 or older server. - * loglevel - (optional) Enable logging of messages from the driver. - * The value is an integer from 1 to 2 where: - * INFO = 1, DEBUG = 2 - * The output is sent to DriverManager.getPrintWriter() if set, - * otherwise it is sent to System.out. - * compatible - (optional) This is used to toggle - * between different functionality as it changes across different releases - * of the jdbc driver code. The values here are versions of the jdbc - * client and not server versions. For example in 7.1 get/setBytes - * worked on LargeObject values, in 7.2 these methods were changed - * to work on bytea values. This change in functionality could - * be disabled by setting the compatible level to be "7.1", in - * which case the driver will revert to the 7.1 functionality. - * - * <p>Normally, at least - * "user" and "password" properties should be included in the - * properties. For a list of supported - * character encoding , see - * http://java.sun.com/products/jdk/1.2/docs/guide/internat/encoding.doc.html - * Note that you will probably want to have set up the Postgres database - * itself to use the same encoding, with the "-E <encoding>" argument - * to createdb. - * - * Our protocol takes the forms: - * <PRE> - * jdbc:postgresql://host:port/database?param1=val1&... - * </PRE> - * - * @param url the URL of the database to connect to - * @param info a list of arbitrary tag/value pairs as connection - * arguments - * @return a connection to the URL or null if it isnt us - * @exception SQLException if a database access error occurs - * @see java.sql.Driver#connect - */ - public java.sql.Connection connect(String url, Properties info) throws SQLException - { - Properties props; - if ((props = parseURL(url, info)) == null) - { - if (Driver.logDebug) - Driver.debug("Error in url" + url); - return null; - } - try - { - if (Driver.logDebug) - Driver.debug("connect " + url); - - @JDBCCONNECTCLASS@ con = (@JDBCCONNECTCLASS@)(Class.forName("@JDBCCONNECTCLASS@").newInstance()); - con.openConnection (host(props), port(props), props, database(props), url, this); - return (java.sql.Connection)con; - } - catch (ClassNotFoundException ex) - { - if (Driver.logDebug) - Driver.debug("error", ex); - throw new PSQLException("postgresql.jvm.version", PSQLState.SYSTEM_ERROR, ex); - } - catch (PSQLException ex1) - { - // re-throw the exception, otherwise it will be caught next, and a - // org.postgresql.unusual error will be returned instead. - throw ex1; - } - catch (Exception ex2) - { - if (Driver.logDebug) { - Driver.debug("error", ex2); - } - throw new PSQLException("postgresql.unusual", PSQLState.UNEXPECTED_ERROR, ex2); - } - } - - /* - * Returns true if the driver thinks it can open a connection to the - * given URL. Typically, drivers will return true if they understand - * the subprotocol specified in the URL and false if they don't. Our - * protocols start with jdbc:postgresql: - * - * @see java.sql.Driver#acceptsURL - * @param url the URL of the driver - * @return true if this driver accepts the given URL - * @exception SQLException if a database-access error occurs - * (Dont know why it would *shrug*) - */ - public boolean acceptsURL(String url) throws SQLException - { - if (parseURL(url, null) == null) - return false; - return true; - } - - /* - * The getPropertyInfo method is intended to allow a generic GUI - * tool to discover what properties it should prompt a human for - * in order to get enough information to connect to a database. - * - * <p>Note that depending on the values the human has supplied so - * far, additional values may become necessary, so it may be necessary - * to iterate through several calls to getPropertyInfo - * - * @param url the Url of the database to connect to - * @param info a proposed list of tag/value pairs that will be sent on - * connect open. - * @return An array of DriverPropertyInfo objects describing - * possible properties. This array may be an empty array if - * no properties are required - * @exception SQLException if a database-access error occurs - * @see java.sql.Driver#getPropertyInfo - */ - public DriverPropertyInfo[] getPropertyInfo(String url, Properties info) throws SQLException - { - //This method isn't really implemented - //we just parse the URL to ensure it is valid - parseURL(url, info); - return new DriverPropertyInfo[0]; - } - - /* - * Gets the drivers major version number - * - * @return the drivers major version number - */ - public int getMajorVersion() - { - return @MAJORVERSION@; - } - - /* - * Get the drivers minor version number - * - * @return the drivers minor version number - */ - public int getMinorVersion() - { - return @MINORVERSION@; - } - - /* - * Returns the VERSION variable from Makefile.global - */ - public static String getVersion() - { - return "@VERSION@ (build " + m_buildNumber + ")"; - } - - /* - * Report whether the driver is a genuine JDBC compliant driver. A - * driver may only report "true" here if it passes the JDBC compliance - * tests, otherwise it is required to return false. JDBC compliance - * requires full support for the JDBC API and full support for SQL 92 - * Entry Level. - * - * <p>For PostgreSQL, this is not yet possible, as we are not SQL92 - * compliant (yet). - */ - public boolean jdbcCompliant() - { - return false; - } - - static private String[] protocols = { "jdbc", "postgresql" }; - - /* - * Constructs a new DriverURL, splitting the specified URL into its - * component parts - * @param url JDBC URL to parse - * @param defaults Default properties - * @return Properties with elements added from the url - * @exception SQLException - */ - Properties parseURL(String url, Properties defaults) throws SQLException - { - int state = -1; - Properties urlProps = new Properties(defaults); - - String l_urlServer = url; - String l_urlArgs = ""; - - int l_qPos = url.indexOf('?'); - if (l_qPos != -1) { - l_urlServer = url.substring(0,l_qPos); - l_urlArgs = url.substring(l_qPos+1); - } - - // look for an IPv6 address that is enclosed by [] - // the upcoming parsing that uses colons as identifiers can't handle - // the colons in an IPv6 address. - int ipv6start = l_urlServer.indexOf("["); - int ipv6end = l_urlServer.indexOf("]"); - String ipv6address = null; - if (ipv6start != -1 && ipv6end > ipv6start) { - ipv6address = l_urlServer.substring(ipv6start+1,ipv6end); - l_urlServer = l_urlServer.substring(0,ipv6start)+"ipv6host"+l_urlServer.substring(ipv6end+1); - } - - //parse the server part of the url - StringTokenizer st = new StringTokenizer(l_urlServer, ":/", true); - int count; - for (count = 0; (st.hasMoreTokens()); count++) - { - String token = st.nextToken(); - - // PM Aug 2 1997 - Modified to allow multiple backends - if (count <= 3) - { - if ((count % 2) == 1 && token.equals(":")) - ; - else if ((count % 2) == 0) - { - boolean found = (count == 0) ? true : false; - for (int tmp = 0;tmp < protocols.length;tmp++) - { - if (token.equals(protocols[tmp])) - { - // PM June 29 1997 Added this property to enable the driver - // to handle multiple backend protocols. - if (count == 2 && tmp > 0) - { - urlProps.put("Protocol", token); - found = true; - } - } - } - - if (found == false) - return null; - } - else - return null; - } - else if (count > 3) - { - if (count == 4 && token.equals("/")) - state = 0; - else if (count == 4) - { - urlProps.put("PGDBNAME", token); - state = -2; - } - else if (count == 5 && state == 0 && token.equals("/")) - state = 1; - else if (count == 5 && state == 0) - return null; - else if (count == 6 && state == 1) - urlProps.put("PGHOST", token); - else if (count == 7 && token.equals(":")) - state = 2; - else if (count == 8 && state == 2) - { - try - { - Integer portNumber = Integer.decode(token); - urlProps.put("PGPORT", portNumber.toString()); - } - catch (Exception e) - { - return null; - } - } - else if ((count == 7 || count == 9) && - (state == 1 || state == 2) && token.equals("/")) - state = -1; - else if (state == -1) - { - urlProps.put("PGDBNAME", token); - state = -2; - } - } - } - if (count <= 1) { - return null; - } - - // if we extracted an IPv6 address out earlier put it back - if (ipv6address != null) - urlProps.put("PGHOST",ipv6address); - - //parse the args part of the url - StringTokenizer qst = new StringTokenizer(l_urlArgs, "&"); - for (count = 0; (qst.hasMoreTokens()); count++) - { - String token = qst.nextToken(); - int l_pos = token.indexOf('='); - if (l_pos == -1) { - urlProps.put(token, ""); - } else { - urlProps.put(token.substring(0,l_pos), token.substring(l_pos+1)); - } - } - - return urlProps; - - } - - /* - * @return the hostname portion of the URL - */ - public String host(Properties props) - { - return props.getProperty("PGHOST", "localhost"); - } - - /* - * @return the port number portion of the URL or the default if no port was specified - */ - public int port(Properties props) - { - return Integer.parseInt(props.getProperty("PGPORT", "@DEF_PGPORT@")); - } - - /* - * @return the database name of the URL - */ - public String database(Properties props) - { - return props.getProperty("PGDBNAME", ""); - } - - /* - * This method was added in v6.5, and simply throws an SQLException - * for an unimplemented method. I decided to do it this way while - * implementing the JDBC2 extensions to JDBC, as it should help keep the - * overall driver size down. - */ - public static SQLException notImplemented() - { - return new PSQLException("postgresql.unimplemented", PSQLState.NOT_IMPLEMENTED); - } - - /** - * used to turn logging on to a certain level, can be called - * by specifying fully qualified class ie org.postgresql.Driver.setLogLevel() - * @param logLevel sets the level which logging will respond to - * INFO being almost no messages - * DEBUG most verbose - */ - public static void setLogLevel(int logLevel) - { - logDebug = (logLevel >= DEBUG) ? true : false; - logInfo = (logLevel >= INFO) ? true : false; - } - /* - * logging message at the debug level - * messages will be printed if the logging level is less or equal to DEBUG - */ - public static void debug(String msg) - { - if (logDebug) - { - DriverManager.println(msg); - } - } - /* - * logging message at the debug level - * messages will be printed if the logging level is less or equal to DEBUG - */ - public static void debug(String msg, Exception ex) - { - if (logDebug) - { - DriverManager.println(msg); - if(ex != null) { - DriverManager.println(ex.toString()); - } - } - } - /* - * logging message at info level - * messages will be printed if the logging level is less or equal to INFO - */ - public static void info(String msg) - { - if (logInfo) - { - DriverManager.println(msg); - } - } - /* - * logging message at info level - * messages will be printed if the logging level is less or equal to INFO - */ - public static void info(String msg, Exception ex) - { - if (logInfo) - { - DriverManager.println(msg); - if(ex != null) { - DriverManager.println(ex.toString()); - } - } - } - - - public static void makeSSL(org.postgresql.core.PGStream p_stream) throws IOException { -@SSL@ if (logDebug) -@SSL@ debug("converting regular socket connection to ssl"); -@SSL@ javax.net.ssl.SSLSocketFactory factory = (javax.net.ssl.SSLSocketFactory) javax.net.ssl.SSLSocketFactory.getDefault(); -@SSL@ p_stream.connection = (javax.net.ssl.SSLSocket) factory.createSocket(p_stream.connection,p_stream.host,p_stream.port,true); -@SSL@ p_stream.pg_input = new BufferedInputStream(p_stream.connection.getInputStream(), 8192); -@SSL@ p_stream.pg_output = new BufferedOutputStream(p_stream.connection.getOutputStream(), 8192); - } - - public static boolean sslEnabled() { - boolean l_return = false; -@SSL@ l_return = true; - return l_return; - } - - - //The build number should be incremented for every new build - private static int m_buildNumber = 300; - -} diff --git a/src/interfaces/jdbc/org/postgresql/PGConnection.java b/src/interfaces/jdbc/org/postgresql/PGConnection.java deleted file mode 100644 index 7871a9d246c..00000000000 --- a/src/interfaces/jdbc/org/postgresql/PGConnection.java +++ /dev/null @@ -1,87 +0,0 @@ -/*------------------------------------------------------------------------- - * - * PGConnection.java - * The public interface definition for a Postgresql Connection - * This interface defines PostgreSQL extentions to the java.sql.Connection - * interface. Any java.sql.Connection object returned by the driver will - * also implement this interface - * - * Copyright (c) 2003, PostgreSQL Global Development Group - * - * IDENTIFICATION - * $PostgreSQL: pgsql/src/interfaces/jdbc/org/postgresql/PGConnection.java,v 1.7 2003/11/29 19:52:09 pgsql Exp $ - * - *------------------------------------------------------------------------- - */ -package org.postgresql; - -import java.sql.*; -import org.postgresql.core.Encoding; -import org.postgresql.fastpath.Fastpath; -import org.postgresql.largeobject.LargeObjectManager; - -public interface PGConnection -{ - /** - * This method returns any notifications that have been received - * since the last call to this method. - * Returns null if there have been no notifications. - * @since 7.3 - */ - public PGNotification[] getNotifications(); - - /** - * This returns the LargeObject API for the current connection. - * @since 7.3 - */ - public LargeObjectManager getLargeObjectAPI() throws SQLException; - - /** - * This returns the Fastpath API for the current connection. - * @since 7.3 - */ - public Fastpath getFastpathAPI() throws SQLException; - - /* - * This allows client code to add a handler for one of org.postgresql's - * more unique data types. - * - * <p><b>NOTE:</b> This is not part of JDBC, but an extension. - * - * <p>The best way to use this is as follows: - * - * <p><pre> - * ... - * ((org.postgresql.PGConnection)myconn).addDataType("mytype","my.class.name"); - * ... - * </pre> - * - * <p>where myconn is an open Connection to org.postgresql. - * - * <p>The handling class must extend org.postgresql.util.PGobject - * - * @see org.postgresql.util.PGobject - */ - public void addDataType(String type, String name); - - - /** @deprecated */ - public Encoding getEncoding() throws SQLException; - - /** @deprecated */ - public int getSQLType(String pgTypeName) throws SQLException; - - /** @deprecated */ - public int getSQLType(int oid) throws SQLException; - - /** @deprecated */ - public String getPGType(int oid) throws SQLException; - - /** @deprecated */ - public int getPGType(String typeName) throws SQLException; - - /** @deprecated */ - public Object getObject(String type, String value) throws SQLException; - -} - diff --git a/src/interfaces/jdbc/org/postgresql/PGNotification.java b/src/interfaces/jdbc/org/postgresql/PGNotification.java deleted file mode 100644 index b6d9f322a24..00000000000 --- a/src/interfaces/jdbc/org/postgresql/PGNotification.java +++ /dev/null @@ -1,31 +0,0 @@ -/*------------------------------------------------------------------------- - * - * PGNotification.java - * This interface defines public PostgreSQL extention for Notifications - * - * Copyright (c) 2003, PostgreSQL Global Development Group - * - * IDENTIFICATION - * $PostgreSQL: pgsql/src/interfaces/jdbc/org/postgresql/PGNotification.java,v 1.4 2003/11/29 19:52:09 pgsql Exp $ - * - *------------------------------------------------------------------------- - */ -package org.postgresql; - - -public interface PGNotification -{ - /** - * Returns name of this notification - * @since 7.3 - */ - public String getName(); - - /** - * Returns the process id of the backend process making this notification - * @since 7.3 - */ - public int getPID(); - -} - diff --git a/src/interfaces/jdbc/org/postgresql/PGRefCursorResultSet.java b/src/interfaces/jdbc/org/postgresql/PGRefCursorResultSet.java deleted file mode 100644 index 411b227a8dc..00000000000 --- a/src/interfaces/jdbc/org/postgresql/PGRefCursorResultSet.java +++ /dev/null @@ -1,25 +0,0 @@ -/*------------------------------------------------------------------------- - * - * PGRefCursorResultSet.java - * Describes a PLPGSQL refcursor type. - * - * Copyright (c) 2003, PostgreSQL Global Development Group - * - * IDENTIFICATION - * $PostgreSQL: pgsql/src/interfaces/jdbc/org/postgresql/PGRefCursorResultSet.java,v 1.2 2003/11/29 19:52:09 pgsql Exp $ - * - *------------------------------------------------------------------------- - */ -package org.postgresql; - - -/** A ref cursor based result set. - */ -public interface PGRefCursorResultSet -{ - - /** return the name of the cursor. - */ - public String getRefCursor (); - -} diff --git a/src/interfaces/jdbc/org/postgresql/PGStatement.java b/src/interfaces/jdbc/org/postgresql/PGStatement.java deleted file mode 100644 index 5bfad1ba7ac..00000000000 --- a/src/interfaces/jdbc/org/postgresql/PGStatement.java +++ /dev/null @@ -1,43 +0,0 @@ -/*------------------------------------------------------------------------- - * - * PGStatement.java - * This interface defines PostgreSQL extentions to the java.sql.Statement - * interface. Any java.sql.Statement object returned by the driver will - * also implement this interface - * - * Copyright (c) 2003, PostgreSQL Global Development Group - * - * IDENTIFICATION - * $PostgreSQL: pgsql/src/interfaces/jdbc/org/postgresql/PGStatement.java,v 1.8 2003/11/29 19:52:09 pgsql Exp $ - * - *------------------------------------------------------------------------- - */ -package org.postgresql; - - -import java.sql.*; - -public interface PGStatement -{ - - /** - * Returns the Last inserted/updated oid. - * @return OID of last insert - * @since 7.3 - */ - public long getLastOID() throws SQLException; - - /** - * Turn on the use of prepared statements in the server (server side - * prepared statements are unrelated to jdbc PreparedStatements) - * @since 7.3 - */ - public void setUseServerPrepare(boolean flag) throws SQLException; - - /** - * Is this statement using server side prepared statements - * @since 7.3 - */ - public boolean isUseServerPrepare(); - -} diff --git a/src/interfaces/jdbc/org/postgresql/core/BaseConnection.java b/src/interfaces/jdbc/org/postgresql/core/BaseConnection.java deleted file mode 100644 index 49320aede89..00000000000 --- a/src/interfaces/jdbc/org/postgresql/core/BaseConnection.java +++ /dev/null @@ -1,47 +0,0 @@ -/*------------------------------------------------------------------------- - * - * BaseConnection.java - * The internal interface definition for a jdbc connection - * - * Copyright (c) 2003, PostgreSQL Global Development Group - * - * IDENTIFICATION - * $PostgreSQL: pgsql/src/interfaces/jdbc/org/postgresql/core/BaseConnection.java,v 1.5 2003/11/29 19:52:09 pgsql Exp $ - * - *------------------------------------------------------------------------- - */ -package org.postgresql.core; - -import java.sql.DatabaseMetaData; -import java.sql.Statement; -import java.sql.SQLException; -import org.postgresql.PGConnection; -import org.postgresql.PGNotification; - -public interface BaseConnection extends PGConnection -{ - - public void addNotification(PGNotification p_notification); - public void addWarning(String msg); - public void cancelQuery() throws SQLException; - public Statement createStatement() throws SQLException; - public BaseResultSet execSQL(String s) throws SQLException; - public boolean getAutoCommit(); - public String getCursorName() throws SQLException; - public Encoding getEncoding() throws SQLException; - public DatabaseMetaData getMetaData() throws SQLException; - public Object getObject(String type, String value) throws SQLException; - public int getPGProtocolVersionMajor(); - public int getPGProtocolVersionMinor(); - public PGStream getPGStream(); - public String getPGType(int oid) throws SQLException; - public int getPGType(String pgTypeName) throws SQLException; - public int getSQLType(int oid) throws SQLException; - public int getSQLType(String pgTypeName) throws SQLException; - public boolean haveMinimumCompatibleVersion(String ver) throws SQLException; - public boolean haveMinimumServerVersion(String ver) throws SQLException; - public void setAutoCommit(boolean autoCommit) throws SQLException; - public void setCursorName(String cursor) throws SQLException; - -} - diff --git a/src/interfaces/jdbc/org/postgresql/core/BaseResultSet.java b/src/interfaces/jdbc/org/postgresql/core/BaseResultSet.java deleted file mode 100644 index 536197cd8e3..00000000000 --- a/src/interfaces/jdbc/org/postgresql/core/BaseResultSet.java +++ /dev/null @@ -1,50 +0,0 @@ -/*------------------------------------------------------------------------- - * - * BaseResultSet.java - * The internal interface definition for a jdbc result set - * - * Copyright (c) 2003, PostgreSQL Global Development Group - * - * IDENTIFICATION - * $PostgreSQL: pgsql/src/interfaces/jdbc/org/postgresql/core/BaseResultSet.java,v 1.3 2003/11/29 19:52:09 pgsql Exp $ - * - *------------------------------------------------------------------------- - */ -package org.postgresql.core; - - -import java.sql.ResultSet; -import java.sql.ResultSetMetaData; -import java.sql.SQLException; -import java.text.SimpleDateFormat; -import java.util.Vector; - -public interface BaseResultSet -{ - - public BaseStatement getPGStatement(); - - public void append(BaseResultSet r); - public void close() throws SQLException; - public int getColumnCount(); - public String getCursorName() throws SQLException; - public SimpleDateFormat getDateFormat(); - public String getFixedString(int col) throws SQLException; - public long getLastOID(); - public ResultSetMetaData getMetaData() throws SQLException; - public ResultSet getNext(); - public Object getObject(int columnIndex) throws SQLException; - public int getResultCount(); - public String getStatusString(); - public String getString(int columnIndex) throws SQLException; - public StringBuffer getStringBuffer(); - public SimpleDateFormat getTimestampFormat(); - public SimpleDateFormat getTimestampTZFormat(); - public int getTupleCount(); - public boolean next() throws SQLException; - public boolean reallyResultSet(); - public void reInit (Field[] fields, Vector tuples, String status, - int updateCount, long insertOID, boolean binaryCursor); - public void setStatement(BaseStatement statement); - -} diff --git a/src/interfaces/jdbc/org/postgresql/core/BaseStatement.java b/src/interfaces/jdbc/org/postgresql/core/BaseStatement.java deleted file mode 100644 index 50113ea8f5f..00000000000 --- a/src/interfaces/jdbc/org/postgresql/core/BaseStatement.java +++ /dev/null @@ -1,41 +0,0 @@ -/*------------------------------------------------------------------------- - * - * BaseStatement.java - * The internal interface definition for a jdbc statement - * - * Copyright (c) 2003, PostgreSQL Global Development Group - * - * IDENTIFICATION - * $PostgreSQL: pgsql/src/interfaces/jdbc/org/postgresql/core/BaseStatement.java,v 1.7 2003/11/29 19:52:09 pgsql Exp $ - * - *------------------------------------------------------------------------- - */ -package org.postgresql.core; - -import org.postgresql.PGRefCursorResultSet; -import java.sql.*; -import java.util.Vector; - -public interface BaseStatement extends org.postgresql.PGStatement -{ - public BaseResultSet createResultSet(Field[] fields, Vector tuples, String status, int updateCount, long insertOID, boolean binaryCursor) throws SQLException; - public PGRefCursorResultSet createRefCursorResultSet(String cursorName) throws SQLException; - - public BaseConnection getPGConnection(); - - /* - * The maxRows limit is set to limit the number of rows that - * any ResultSet can contain. If the limit is exceeded, the - * excess rows are silently dropped. - */ - public void addWarning(String p_warning) throws SQLException; - public void close() throws SQLException; - public int getFetchSize(); - public int getMaxFieldSize() throws SQLException; - public int getMaxRows() throws SQLException; - public int getResultSetConcurrency() throws SQLException; - public String getFetchingCursorName(); - public SQLWarning getWarnings() throws SQLException; - public void setMaxFieldSize(int max) throws SQLException; - -} diff --git a/src/interfaces/jdbc/org/postgresql/core/Encoding.java b/src/interfaces/jdbc/org/postgresql/core/Encoding.java deleted file mode 100644 index b3312bea417..00000000000 --- a/src/interfaces/jdbc/org/postgresql/core/Encoding.java +++ /dev/null @@ -1,291 +0,0 @@ -/*------------------------------------------------------------------------- - * - * Encoding.java - * Converts to and from the character encoding used by the backend. - * - * Copyright (c) 2003, PostgreSQL Global Development Group - * - * IDENTIFICATION - * $PostgreSQL: pgsql/src/interfaces/jdbc/org/postgresql/core/Encoding.java,v 1.13 2003/11/29 19:52:09 pgsql Exp $ - * - *------------------------------------------------------------------------- - */ -package org.postgresql.core; - -import java.io.InputStream; -import java.io.InputStreamReader; -import java.io.Reader; -import java.io.UnsupportedEncodingException; -import java.sql.SQLException; -import java.util.Hashtable; -import org.postgresql.util.PSQLException; -import org.postgresql.util.PSQLState; - -public class Encoding -{ - - private static final Encoding DEFAULT_ENCODING = new Encoding(null); - - /* - * Preferred JVM encodings for backend encodings. - */ - private static final Hashtable encodings = new Hashtable(); - - static { - //Note: this list should match the set of supported server - // encodings found in backend/util/mb/encnames.c - encodings.put("SQL_ASCII", new String[] { "ASCII", "us-ascii" }); - encodings.put("UNICODE", new String[] { "UTF-8", "UTF8" }); - encodings.put("LATIN1", new String[] { "ISO8859_1" }); - encodings.put("LATIN2", new String[] { "ISO8859_2" }); - encodings.put("LATIN3", new String[] { "ISO8859_3" }); - encodings.put("LATIN4", new String[] { "ISO8859_4" }); - encodings.put("ISO_8859_5", new String[] { "ISO8859_5" }); - encodings.put("ISO_8859_6", new String[] { "ISO8859_6" }); - encodings.put("ISO_8859_7", new String[] { "ISO8859_7" }); - encodings.put("ISO_8859_8", new String[] { "ISO8859_8" }); - encodings.put("LATIN5", new String[] { "ISO8859_9" }); - encodings.put("LATIN7", new String[] { "ISO8859_13" }); - encodings.put("LATIN9", new String[] { "ISO8859_15_FDIS" }); - encodings.put("EUC_JP", new String[] { "EUC_JP" }); - encodings.put("EUC_CN", new String[] { "EUC_CN" }); - encodings.put("EUC_KR", new String[] { "EUC_KR" }); - encodings.put("JOHAB", new String[] { "Johab" }); - encodings.put("EUC_TW", new String[] { "EUC_TW" }); - encodings.put("SJIS", new String[] { "MS932", "SJIS" }); - encodings.put("BIG5", new String[] { "Big5", "MS950", "Cp950" }); - encodings.put("GBK", new String[] { "GBK", "MS936" }); - encodings.put("UHC", new String[] { "MS949", "Cp949", "Cp949C" }); - encodings.put("TCVN", new String[] { "Cp1258" }); - encodings.put("WIN1256", new String[] { "Cp1256" }); - encodings.put("WIN1250", new String[] { "Cp1250" }); - encodings.put("WIN874", new String[] { "MS874", "Cp874" }); - encodings.put("WIN", new String[] { "Cp1251" }); - encodings.put("ALT", new String[] { "Cp866" }); - // We prefer KOI8-U, since it is a superset of KOI8-R. - encodings.put("KOI8", new String[] { "KOI8_U", "KOI8_R" }); - // If the database isn't encoding-aware then we can't have - // any preferred encodings. - encodings.put("UNKNOWN", new String[0]); - // The following encodings do not have a java equivalent - encodings.put("MULE_INTERNAL", new String[0]); - encodings.put("LATIN6", new String[0]); - encodings.put("LATIN8", new String[0]); - encodings.put("LATIN10", new String[0]); - } - - private final String encoding; - - private Encoding(String encoding) - { - this.encoding = encoding; - } - - /* - * Get an Encoding for from the given database encoding and - * the encoding passed in by the user. - */ - public static Encoding getEncoding(String databaseEncoding, - String passedEncoding) - { - if (passedEncoding != null) - { - if (isAvailable(passedEncoding)) - { - return new Encoding(passedEncoding); - } - else - { - return defaultEncoding(); - } - } - else - { - return encodingForDatabaseEncoding(databaseEncoding); - } - } - - /* - * Get an Encoding matching the given database encoding. - */ - private static Encoding encodingForDatabaseEncoding(String databaseEncoding) - { - // If the backend encoding is known and there is a suitable - // encoding in the JVM we use that. Otherwise we fall back - // to the default encoding of the JVM. - - if (encodings.containsKey(databaseEncoding)) - { - String[] candidates = (String[]) encodings.get(databaseEncoding); - for (int i = 0; i < candidates.length; i++) - { - if (isAvailable(candidates[i])) - { - return new Encoding(candidates[i]); - } - } - } - return defaultEncoding(); - } - - /* - * Name of the (JVM) encoding used. - */ - public String name() - { - return encoding; - } - - /* - * Encode a string to an array of bytes. - */ - public byte[] encode(String s) throws SQLException - { - byte[] l_return; - try - { - if (encoding == null) - { - l_return = s.getBytes(); - } - else - { - l_return = s.getBytes(encoding); - } - //Don't return null, return an empty byte[] instead - if (l_return == null) { - return new byte[0]; - } else { - return l_return; - } - } - catch (UnsupportedEncodingException e) - { - throw new PSQLException("postgresql.stream.encoding", PSQLState.DATA_ERROR, e); - } - } - - /* - * Decode an array of bytes into a string. - */ - public String decode(byte[] encodedString, int offset, int length) throws SQLException - { - try - { - if (encoding == null) - { - return new String(encodedString, offset, length); - } - else - { - if (encoding.equals("UTF-8")) { - return decodeUTF8(encodedString, offset, length); - } - return new String(encodedString, offset, length, encoding); - } - } - catch (UnsupportedEncodingException e) - { - throw new PSQLException("postgresql.stream.encoding", PSQLState.DATA_ERROR, e); - } - } - - /* - * Decode an array of bytes into a string. - */ - public String decode(byte[] encodedString) throws SQLException - { - return decode(encodedString, 0, encodedString.length); - } - - /* - * Get a Reader that decodes the given InputStream. - */ - public Reader getDecodingReader(InputStream in) throws SQLException - { - try - { - if (encoding == null) - { - return new InputStreamReader(in); - } - else - { - return new InputStreamReader(in, encoding); - } - } - catch (UnsupportedEncodingException e) - { - throw new PSQLException("postgresql.res.encoding", PSQLState.DATA_ERROR, e); - } - } - - /* - * Get an Encoding using the default encoding for the JVM. - */ - public static Encoding defaultEncoding() - { - return DEFAULT_ENCODING; - } - - /* - * Test if an encoding is available in the JVM. - */ - private static boolean isAvailable(String encodingName) - { - try - { - "DUMMY".getBytes(encodingName); - return true; - } - catch (UnsupportedEncodingException e) - { - return false; - } - } - - /** - * custom byte[] -> String conversion routine, 3x-10x faster than - * standard new String(byte[]) - */ - private static final int pow2_6 = 64; // 26 - private static final int pow2_12 = 4096; // 212 - private char[] cdata = new char[50]; - - private synchronized String decodeUTF8(byte data[], int offset, int length) throws SQLException { - try { - char[] l_cdata = cdata; - if (l_cdata.length < (length)) { - l_cdata = new char[length]; - } - int i = offset; - int j = 0; - int k = length + offset; - int z, y, x, val; - while (i < k) { - z = data[i] & 0xFF; - if (z < 0x80) { - l_cdata[j++] = (char)data[i]; - i++; - } else if (z >= 0xE0) { // length == 3 - y = data[i+1] & 0xFF; - x = data[i+2] & 0xFF; - val = (z-0xE0)*pow2_12 + (y-0x80)*pow2_6 + (x-0x80); - l_cdata[j++] = (char) val; - i+= 3; - } else { // length == 2 (maybe add checking for length > 3, throw exception if it is - y = data[i+1] & 0xFF; - val = (z - 0xC0)* (pow2_6)+(y-0x80); - l_cdata[j++] = (char) val; - i+=2; - } - } - - String s = new String(l_cdata, 0, j); - return s; - } catch (Exception l_e) { - throw new PSQLException("postgresql.con.invalidchar", l_e); - } - } - -} diff --git a/src/interfaces/jdbc/org/postgresql/core/Field.java b/src/interfaces/jdbc/org/postgresql/core/Field.java deleted file mode 100644 index 08d143f636c..00000000000 --- a/src/interfaces/jdbc/org/postgresql/core/Field.java +++ /dev/null @@ -1,114 +0,0 @@ -/*------------------------------------------------------------------------- - * - * Field.java - * Field is a class used to describe fields in a PostgreSQL ResultSet - * - * Copyright (c) 2003, PostgreSQL Global Development Group - * - * IDENTIFICATION - * $PostgreSQL: pgsql/src/interfaces/jdbc/org/postgresql/core/Field.java,v 1.3 2003/11/29 19:52:09 pgsql Exp $ - * - *------------------------------------------------------------------------- - */ -package org.postgresql.core; - -import java.sql.*; -import org.postgresql.core.BaseConnection; - -/* - */ -public class Field -{ - private int length; // Internal Length of this field - private int oid; // OID of the type - private int mod; // type modifier of this field - private String name; // Name of this field - - private BaseConnection conn; // Connection Instantation - - - /* - * Construct a field based on the information fed to it. - * - * @param conn the connection this field came from - * @param name the name of the field - * @param oid the OID of the field - * @param len the length of the field - */ - public Field(BaseConnection conn, String name, int oid, int length, int mod) - { - this.conn = conn; - this.name = name; - this.oid = oid; - this.length = length; - this.mod = mod; - } - - /* - * Constructor without mod parameter. - * - * @param conn the connection this field came from - * @param name the name of the field - * @param oid the OID of the field - * @param len the length of the field - */ - public Field(BaseConnection conn, String name, int oid, int length) - { - this(conn, name, oid, length, 0); - } - - /* - * @return the oid of this Field's data type - */ - public int getOID() - { - return oid; - } - - /* - * @return the mod of this Field's data type - */ - public int getMod() - { - return mod; - } - - /* - * @return the name of this Field's data type - */ - public String getName() - { - return name; - } - - /* - * @return the length of this Field's data type - */ - public int getLength() - { - return length; - } - - /* - * We also need to get the PG type name as returned by the back end. - * - * @return the String representation of the PG type of this field - * @exception SQLException if a database access error occurs - */ - public String getPGType() throws SQLException - { - return conn.getPGType(oid); - } - - /* - * We also need to get the java.sql.types type. - * - * @return the int representation of the java.sql.types type of this field - * @exception SQLException if a database access error occurs - */ - public int getSQLType() throws SQLException - { - return conn.getSQLType(oid); - } - -} diff --git a/src/interfaces/jdbc/org/postgresql/core/Notification.java b/src/interfaces/jdbc/org/postgresql/core/Notification.java deleted file mode 100644 index dec41426afd..00000000000 --- a/src/interfaces/jdbc/org/postgresql/core/Notification.java +++ /dev/null @@ -1,45 +0,0 @@ -/*------------------------------------------------------------------------- - * - * Notification.java - * This is the implementation of the PGNotification interface - * - * Copyright (c) 2003, PostgreSQL Global Development Group - * - * IDENTIFICATION - * $PostgreSQL: pgsql/src/interfaces/jdbc/org/postgresql/core/Notification.java,v 1.4 2003/11/29 19:52:09 pgsql Exp $ - * - *------------------------------------------------------------------------- - */ -package org.postgresql.core; - -import org.postgresql.PGNotification; - -public class Notification implements PGNotification -{ - public Notification(String p_name, int p_pid) - { - m_name = p_name; - m_pid = p_pid; - } - - /* - * Returns name of this notification - */ - public String getName() - { - return m_name; - } - - /* - * Returns the process id of the backend process making this notification - */ - public int getPID() - { - return m_pid; - } - - private String m_name; - private int m_pid; - -} - diff --git a/src/interfaces/jdbc/org/postgresql/core/PGStream.java b/src/interfaces/jdbc/org/postgresql/core/PGStream.java deleted file mode 100644 index 28d516acaa7..00000000000 --- a/src/interfaces/jdbc/org/postgresql/core/PGStream.java +++ /dev/null @@ -1,431 +0,0 @@ -/*------------------------------------------------------------------------- - * - * PGStream.java - * This class is used by Connection for communicating with the - * backend. - * - * Copyright (c) 2003, PostgreSQL Global Development Group - * - * IDENTIFICATION - * $PostgreSQL: pgsql/src/interfaces/jdbc/org/postgresql/core/PGStream.java,v 1.4 2003/11/29 19:52:09 pgsql Exp $ - * - *------------------------------------------------------------------------- - */ -package org.postgresql.core; - -import java.io.BufferedInputStream; -import java.io.BufferedOutputStream; -import java.io.InputStream; -import java.io.IOException; -import java.net.Socket; -import java.sql.*; -import org.postgresql.util.PSQLException; -import org.postgresql.util.PSQLState; - - -public class PGStream -{ - public String host; - public int port; - public Socket connection; - public InputStream pg_input; - public BufferedOutputStream pg_output; - private byte[] byte_buf = new byte[8*1024]; - - /* - * Constructor: Connect to the PostgreSQL back end and return - * a stream connection. - * - * @param host the hostname to connect to - * @param port the port number that the postmaster is sitting on - * @exception IOException if an IOException occurs below it. - */ - public PGStream(String p_host, int p_port) throws IOException - { - host = p_host; - port = p_port; - connection = new Socket(host, port); - - // Submitted by Jason Venner <[email protected]> adds a 10x speed - // improvement on FreeBSD machines (caused by a bug in their TCP Stack) - connection.setTcpNoDelay(true); - - // Buffer sizes submitted by Sverre H Huseby <[email protected]> - pg_input = new BufferedInputStream(connection.getInputStream(), 8192); - pg_output = new BufferedOutputStream(connection.getOutputStream(), 8192); - } - - /* - * Sends a single character to the back end - * - * @param val the character to be sent - * @exception IOException if an I/O error occurs - */ - public void SendChar(int val) throws IOException - { - pg_output.write((byte)val); - } - - /* - * Sends an integer to the back end - * - * @param val the integer to be sent - * @param siz the length of the integer in bytes (size of structure) - * @exception IOException if an I/O error occurs - */ - public void SendInteger(int val, int siz) throws IOException - { - byte[] buf = new byte[siz]; - - while (siz-- > 0) - { - buf[siz] = (byte)(val & 0xff); - val >>= 8; - } - Send(buf); - } - - /* - * Sends an integer to the back end - * - * @param val the integer to be sent - * @param siz the length of the integer in bytes (size of structure) - * @exception IOException if an I/O error occurs - */ - public void SendIntegerR(int val, int siz) throws IOException - { - byte[] buf = new byte[siz]; - - for (int i = 0; i < siz; i++) - { - buf[i] = (byte)(val & 0xff); - val >>= 8; - } - Send(buf); - } - - /* - * Send an array of bytes to the backend - * - * @param buf The array of bytes to be sent - * @exception IOException if an I/O error occurs - */ - public void Send(byte buf[]) throws IOException - { - pg_output.write(buf); - } - - /* - * Send an exact array of bytes to the backend - if the length - * has not been reached, send nulls until it has. - * - * @param buf the array of bytes to be sent - * @param siz the number of bytes to be sent - * @exception IOException if an I/O error occurs - */ - public void Send(byte buf[], int siz) throws IOException - { - Send(buf, 0, siz); - } - - /* - * Send an exact array of bytes to the backend - if the length - * has not been reached, send nulls until it has. - * - * @param buf the array of bytes to be sent - * @param off offset in the array to start sending from - * @param siz the number of bytes to be sent - * @exception IOException if an I/O error occurs - */ - public void Send(byte buf[], int off, int siz) throws IOException - { - int i; - - pg_output.write(buf, off, ((buf.length - off) < siz ? (buf.length - off) : siz)); - if ((buf.length - off) < siz) - { - for (i = buf.length - off ; i < siz ; ++i) - { - pg_output.write(0); - } - } - } - - /* - * Receives a single character from the backend - * - * @return the character received - * @exception SQLException if an I/O Error returns - */ - public int ReceiveChar() throws SQLException - { - int c = 0; - - try - { - c = pg_input.read(); - if (c < 0) - throw new PSQLException("postgresql.stream.eof", PSQLState.COMMUNICATION_ERROR); - } - catch (IOException e) - { - throw new PSQLException("postgresql.stream.ioerror", PSQLState.COMMUNICATION_ERROR, e); - } - return c; - } - - /* - * Receives an integer from the backend - * - * @param siz length of the integer in bytes - * @return the integer received from the backend - * @exception SQLException if an I/O error occurs - */ - public int ReceiveInteger(int siz) throws SQLException - { - int n = 0; - - try - { - for (int i = 0 ; i < siz ; i++) - { - int b = pg_input.read(); - - if (b < 0) - throw new PSQLException("postgresql.stream.eof", PSQLState.COMMUNICATION_ERROR); - n = n | (b << (8 * i)) ; - } - } - catch (IOException e) - { - throw new PSQLException("postgresql.stream.ioerror", PSQLState.COMMUNICATION_ERROR, e); - } - return n; - } - - /* - * Receives an integer from the backend - * - * @param siz length of the integer in bytes - * @return the integer received from the backend - * @exception SQLException if an I/O error occurs - */ - public int ReceiveIntegerR(int siz) throws SQLException - { - int n = 0; - - try - { - for (int i = 0 ; i < siz ; i++) - { - int b = pg_input.read(); - - if (b < 0) - throw new PSQLException("postgresql.stream.eof", PSQLState.COMMUNICATION_ERROR); - n = b | (n << 8); - } - } - catch (IOException e) - { - throw new PSQLException("postgresql.stream.ioerror", PSQLState.COMMUNICATION_ERROR, e); - } - return n; - } - - /* - * Receives a null-terminated string from the backend. If we don't see a - * null, then we assume something has gone wrong. - * - * @param encoding the charset encoding to use. - * @return string from back end - * @exception SQLException if an I/O error occurs, or end of file - */ - public String ReceiveString(Encoding encoding) - throws SQLException - { - int s = 0; - byte[] rst = byte_buf; - try - { - int buflen = rst.length; - boolean done = false; - while (!done) - { - while (s < buflen) - { - int c = pg_input.read(); - if (c < 0) - throw new PSQLException("postgresql.stream.eof", PSQLState.COMMUNICATION_ERROR); - else if (c == 0) - { - rst[s] = 0; - done = true; - break; - } - else - { - rst[s++] = (byte)c; - } - if (s >= buflen) - { // Grow the buffer - buflen = (int)(buflen * 2); // 100% bigger - byte[] newrst = new byte[buflen]; - System.arraycopy(rst, 0, newrst, 0, s); - rst = newrst; - } - } - } - } - catch (IOException e) - { - throw new PSQLException("postgresql.stream.ioerror", PSQLState.COMMUNICATION_ERROR, e); - } - return encoding.decode(rst, 0, s); - } - - /* - * Read a tuple from the back end. A tuple is a two dimensional - * array of bytes - * - * @param nf the number of fields expected - * @param bin true if the tuple is a binary tuple - * @return null if the current response has no more tuples, otherwise - * an array of strings - * @exception SQLException if a data I/O error occurs - */ - public byte[][] ReceiveTupleV3(int nf, boolean bin) throws SQLException - { - //TODO: use l_msgSize - int l_msgSize = ReceiveIntegerR(4); - int i; - int l_nf = ReceiveIntegerR(2); - byte[][] answer = new byte[l_nf][0]; - - for (i = 0 ; i < l_nf ; ++i) - { - int l_size = ReceiveIntegerR(4); - boolean isNull = l_size == -1; - if (isNull) - answer[i] = null; - else - { - answer[i] = Receive(l_size); - } - } - return answer; - } - - /* - * Read a tuple from the back end. A tuple is a two dimensional - * array of bytes - * - * @param nf the number of fields expected - * @param bin true if the tuple is a binary tuple - * @return null if the current response has no more tuples, otherwise - * an array of strings - * @exception SQLException if a data I/O error occurs - */ - public byte[][] ReceiveTupleV2(int nf, boolean bin) throws SQLException - { - int i, bim = (nf + 7) / 8; - byte[] bitmask = Receive(bim); - byte[][] answer = new byte[nf][0]; - - int whichbit = 0x80; - int whichbyte = 0; - - for (i = 0 ; i < nf ; ++i) - { - boolean isNull = ((bitmask[whichbyte] & whichbit) == 0); - whichbit >>= 1; - if (whichbit == 0) - { - ++whichbyte; - whichbit = 0x80; - } - if (isNull) - answer[i] = null; - else - { - int len = ReceiveIntegerR(4); - if (!bin) - len -= 4; - if (len < 0) - len = 0; - answer[i] = Receive(len); - } - } - return answer; - } - - /* - * Reads in a given number of bytes from the backend - * - * @param siz number of bytes to read - * @return array of bytes received - * @exception SQLException if a data I/O error occurs - */ - public byte[] Receive(int siz) throws SQLException - { - byte[] answer = new byte[siz]; - Receive(answer, 0, siz); - return answer; - } - - /* - * Reads in a given number of bytes from the backend - * - * @param buf buffer to store result - * @param off offset in buffer - * @param siz number of bytes to read - * @exception SQLException if a data I/O error occurs - */ - public void Receive(byte[] b, int off, int siz) throws SQLException - { - int s = 0; - - try - { - while (s < siz) - { - int w = pg_input.read(b, off + s, siz - s); - if (w < 0) - throw new PSQLException("postgresql.stream.eof", PSQLState.COMMUNICATION_ERROR); - s += w; - } - } - catch (IOException e) - { - throw new PSQLException("postgresql.stream.ioerror", PSQLState.COMMUNICATION_ERROR, e); - } - } - - /* - * This flushes any pending output to the backend. It is used primarily - * by the Fastpath code. - * @exception SQLException if an I/O error occurs - */ - public void flush() throws SQLException - { - try - { - pg_output.flush(); - } - catch (IOException e) - { - throw new PSQLException("postgresql.stream.flush", PSQLState.COMMUNICATION_ERROR, e); - } - } - - /* - * Closes the connection - * - * @exception IOException if a IO Error occurs - */ - public void close() throws IOException - { - pg_output.close(); - pg_input.close(); - connection.close(); - } -} diff --git a/src/interfaces/jdbc/org/postgresql/core/QueryExecutor.java b/src/interfaces/jdbc/org/postgresql/core/QueryExecutor.java deleted file mode 100644 index b1d69ce0c75..00000000000 --- a/src/interfaces/jdbc/org/postgresql/core/QueryExecutor.java +++ /dev/null @@ -1,511 +0,0 @@ -/*------------------------------------------------------------------------- - * - * QueryExecutor.java - * Executes a query on the backend. - * - * Copyright (c) 2003, PostgreSQL Global Development Group - * - * IDENTIFICATION - * $PostgreSQL: pgsql/src/interfaces/jdbc/org/postgresql/core/QueryExecutor.java,v 1.28 2003/11/29 19:52:09 pgsql Exp $ - * - *------------------------------------------------------------------------- - */ -package org.postgresql.core; - -import java.util.Vector; -import java.io.IOException; -import java.sql.*; -import org.postgresql.Driver; -import org.postgresql.util.PSQLException; -import org.postgresql.util.PSQLState; - -public class QueryExecutor -{ - //This version of execute does not take an existing result set, but - //creates a new one for the results of the query - public static BaseResultSet execute(String[] p_sqlFrags, - Object[] p_binds, - BaseStatement statement) - throws SQLException - { - QueryExecutor qe = new QueryExecutor(); - qe.m_sqlFrags = p_sqlFrags; - qe.m_binds = p_binds; - qe.statement = statement; - if (statement != null) - qe.maxRows = statement.getMaxRows(); - else - qe.maxRows = 0; - - qe.connection = statement.getPGConnection(); - qe.pgStream = qe.connection.getPGStream(); - - return qe.execute(); - } - - //This version of execute reuses an existing result set for the query - //results, this is used when a result set is backed by a cursor and - //more results are fetched - public static void execute(String[] p_sqlFrags, - Object[] p_binds, - BaseResultSet rs) - throws SQLException - { - QueryExecutor qe = new QueryExecutor(); - qe.m_sqlFrags = p_sqlFrags; - qe.m_binds = p_binds; - qe.rs = rs; - qe.statement = qe.rs.getPGStatement(); - if (qe.statement != null) - qe.maxRows = qe.statement.getMaxRows(); - else - qe.maxRows = 0; - - qe.connection = qe.statement.getPGConnection(); - qe.pgStream = qe.connection.getPGStream(); - - qe.execute(); - } - - - private QueryExecutor () - { - } - - private String[] m_sqlFrags; - private Object[] m_binds; - private BaseStatement statement; - private BaseResultSet rs; - - private BaseConnection connection; - private PGStream pgStream; - - private Field[] fields = null; - private Vector tuples = new Vector(); - private boolean binaryCursor = false; - private String status = null; - private int update_count = 1; - private long insert_oid = 0; - private int maxRows; - - - /* - * Execute a query on the backend. - * - */ - private BaseResultSet execute() throws SQLException - { - if (connection.getPGProtocolVersionMajor() == 3) { - if (Driver.logDebug) - Driver.debug("Using Protocol Version3 to send query"); - return executeV3(); - } else { - if (Driver.logDebug) - Driver.debug("Using Protocol Version2 to send query"); - return executeV2(); - } - } - - private BaseResultSet executeV3() throws SQLException - { - - PSQLException error = null; - - if (pgStream == null) - { - throw new PSQLException("postgresql.con.closed", PSQLState.CONNECTION_DOES_NOT_EXIST); - } - - synchronized (pgStream) - { - - sendQueryV3(); - - int c; - boolean l_endQuery = false; - while (!l_endQuery) - { - c = pgStream.ReceiveChar(); - switch (c) - { - case 'A': // Asynchronous Notify - int pid = pgStream.ReceiveInteger(4); - String msg = pgStream.ReceiveString(connection.getEncoding()); - connection.addNotification(new org.postgresql.core.Notification(msg, pid)); - break; - case 'B': // Binary Data Transfer - receiveTupleV3(true); - break; - case 'C': // Command Status - receiveCommandStatusV3(); - break; - case 'D': // Text Data Transfer - receiveTupleV3(false); - break; - case 'E': // Error Message - - // it's possible to get more than one error message for a query - // see libpq comments wrt backend closing a connection - // so, append messages to a string buffer and keep processing - // check at the bottom to see if we need to throw an exception - - int l_elen = pgStream.ReceiveIntegerR(4); - String totalMessage = connection.getEncoding().decode(pgStream.Receive(l_elen-4)); - PSQLException l_error = PSQLException.parseServerError(totalMessage); - - if (error != null) { - error.setNextException(l_error); - } else { - error = l_error; - } - - // keep processing - break; - case 'I': // Empty Query - int t = pgStream.ReceiveIntegerR(4); - break; - case 'N': // Error Notification - int l_nlen = pgStream.ReceiveIntegerR(4); - statement.addWarning(connection.getEncoding().decode(pgStream.Receive(l_nlen-4))); - break; - case 'P': // Portal Name - String pname = pgStream.ReceiveString(connection.getEncoding()); - break; - case 'S': - //TODO: handle parameter status messages - int l_len = pgStream.ReceiveIntegerR(4); - String l_pStatus = connection.getEncoding().decode(pgStream.Receive(l_len-4)); - if (Driver.logDebug) - Driver.debug("ParameterStatus="+ l_pStatus); - break; - case 'T': // MetaData Field Description - receiveFieldsV3(); - break; - case 'Z': - // read ReadyForQuery - //TODO: use size better - if (pgStream.ReceiveIntegerR(4) != 5) throw new PSQLException("postgresql.con.setup", PSQLState.CONNECTION_UNABLE_TO_CONNECT); - //TODO: handle transaction status - char l_tStatus = (char)pgStream.ReceiveChar(); - l_endQuery = true; - break; - default: - throw new PSQLException("postgresql.con.type", PSQLState.CONNECTION_FAILURE, new Character((char) c)); - } - - } - - // did we get an error during this query? - if ( error != null ) - throw error; - - //if an existing result set was passed in reuse it, else - //create a new one - if (rs != null) - { - rs.reInit(fields, tuples, status, update_count, insert_oid, binaryCursor); - } - else - { - rs = statement.createResultSet(fields, tuples, status, update_count, insert_oid, binaryCursor); - } - return rs; - } - } - - private BaseResultSet executeV2() throws SQLException - { - - StringBuffer errorMessage = null; - - if (pgStream == null) - { - throw new PSQLException("postgresql.con.closed", PSQLState.CONNECTION_DOES_NOT_EXIST); - } - - synchronized (pgStream) - { - - sendQueryV2(); - - int c; - boolean l_endQuery = false; - while (!l_endQuery) - { - c = pgStream.ReceiveChar(); - - switch (c) - { - case 'A': // Asynchronous Notify - int pid = pgStream.ReceiveInteger(4); - String msg = pgStream.ReceiveString(connection.getEncoding()); - connection.addNotification(new org.postgresql.core.Notification(msg, pid)); - break; - case 'B': // Binary Data Transfer - receiveTupleV2(true); - break; - case 'C': // Command Status - receiveCommandStatusV2(); - break; - case 'D': // Text Data Transfer - receiveTupleV2(false); - break; - case 'E': // Error Message - - // it's possible to get more than one error message for a query - // see libpq comments wrt backend closing a connection - // so, append messages to a string buffer and keep processing - // check at the bottom to see if we need to throw an exception - - if ( errorMessage == null ) - errorMessage = new StringBuffer(); - - errorMessage.append(pgStream.ReceiveString(connection.getEncoding())); - // keep processing - break; - case 'I': // Empty Query - int t = pgStream.ReceiveIntegerR(4); - break; - case 'N': // Error Notification - statement.addWarning(pgStream.ReceiveString(connection.getEncoding())); - break; - case 'P': // Portal Name - String pname = pgStream.ReceiveString(connection.getEncoding()); - break; - case 'T': // MetaData Field Description - receiveFieldsV2(); - break; - case 'Z': - l_endQuery = true; - break; - default: - throw new PSQLException("postgresql.con.type", PSQLState.CONNECTION_FAILURE, new Character((char) c)); - } - - } - - // did we get an error during this query? - if ( errorMessage != null ) - throw new SQLException( errorMessage.toString().trim() ); - - - //if an existing result set was passed in reuse it, else - //create a new one - if (rs != null) - { - rs.reInit(fields, tuples, status, update_count, insert_oid, binaryCursor); - } - else - { - rs = statement.createResultSet(fields, tuples, status, update_count, insert_oid, binaryCursor); - } - return rs; - } - } - - /* - * Send a query to the backend. - */ - private void sendQueryV3() throws SQLException - { - for ( int i = 0; i < m_binds.length ; i++ ) - { - if ( m_binds[i] == null ) - throw new PSQLException("postgresql.prep.param", PSQLState.INVALID_PARAMETER_VALUE, new Integer(i + 1)); - } - try - { - byte[][] l_parts = new byte[(m_binds.length*2)+1][]; - int j = 0; - int l_msgSize = 4; - Encoding l_encoding = connection.getEncoding(); - pgStream.SendChar('Q'); - for (int i = 0 ; i < m_binds.length ; ++i) - { - l_parts[j] = l_encoding.encode(m_sqlFrags[i]); - l_msgSize += l_parts[j].length; - j++; - l_parts[j] = l_encoding.encode(m_binds[i].toString()); - l_msgSize += l_parts[j].length; - j++; - } - l_parts[j] = l_encoding.encode(m_sqlFrags[m_binds.length]); - l_msgSize += l_parts[j].length; - pgStream.SendInteger(l_msgSize+1,4); - for (int k = 0; k < l_parts.length; k++) { - pgStream.Send(l_parts[k]); - } - pgStream.SendChar(0); - pgStream.flush(); - } - catch (IOException e) - { - throw new PSQLException("postgresql.con.ioerror", PSQLState.CONNECTION_FAILURE_DURING_TRANSACTION, e); - } - } - - /* - * Send a query to the backend. - */ - private void sendQueryV2() throws SQLException - { - for ( int i = 0; i < m_binds.length ; i++ ) - { - if ( m_binds[i] == null ) - throw new PSQLException("postgresql.prep.param", PSQLState.INVALID_PARAMETER_VALUE, new Integer(i + 1)); - } - try - { - pgStream.SendChar('Q'); - for (int i = 0 ; i < m_binds.length ; ++i) - { - pgStream.Send(connection.getEncoding().encode(m_sqlFrags[i])); - pgStream.Send(connection.getEncoding().encode(m_binds[i].toString())); - } - - pgStream.Send(connection.getEncoding().encode(m_sqlFrags[m_binds.length])); - pgStream.SendChar(0); - pgStream.flush(); - - } - catch (IOException e) - { - throw new PSQLException("postgresql.con.ioerror", PSQLState.CONNECTION_FAILURE_DURING_TRANSACTION, e); - } - } - - /* - * Receive a tuple from the backend. - * - * @param isBinary set if the tuple should be treated as binary data - */ - private void receiveTupleV3(boolean isBinary) throws SQLException - { - if (fields == null) - throw new PSQLException("postgresql.con.tuple", PSQLState.CONNECTION_FAILURE); - Object tuple = pgStream.ReceiveTupleV3(fields.length, isBinary); - if (isBinary) - binaryCursor = true; - if (maxRows == 0 || tuples.size() < maxRows) - tuples.addElement(tuple); - } - - /* - * Receive a tuple from the backend. - * - * @param isBinary set if the tuple should be treated as binary data - */ - private void receiveTupleV2(boolean isBinary) throws SQLException - { - if (fields == null) - throw new PSQLException("postgresql.con.tuple", PSQLState.CONNECTION_FAILURE); - Object tuple = pgStream.ReceiveTupleV2(fields.length, isBinary); - if (isBinary) - binaryCursor = true; - if (maxRows == 0 || tuples.size() < maxRows) - tuples.addElement(tuple); - } - - /* - * Receive command status from the backend. - */ - private void receiveCommandStatusV3() throws SQLException - { - //TODO: better handle the msg len - int l_len = pgStream.ReceiveIntegerR(4); - //read l_len -5 bytes (-4 for l_len and -1 for trailing \0) - status = connection.getEncoding().decode(pgStream.Receive(l_len-5)); - //now read and discard the trailing \0 - pgStream.Receive(1); - try - { - // Now handle the update count correctly. - if (status.startsWith("INSERT") || status.startsWith("UPDATE") || status.startsWith("DELETE") || status.startsWith("MOVE")) - { - update_count = Integer.parseInt(status.substring(1 + status.lastIndexOf(' '))); - } - if (status.startsWith("INSERT")) - { - insert_oid = Long.parseLong(status.substring(1 + status.indexOf(' '), - status.lastIndexOf(' '))); - } - } - catch (NumberFormatException nfe) - { - throw new PSQLException("postgresql.con.fathom", PSQLState.CONNECTION_FAILURE, status); - } - } - /* - * Receive command status from the backend. - */ - private void receiveCommandStatusV2() throws SQLException - { - - status = pgStream.ReceiveString(connection.getEncoding()); - - try - { - // Now handle the update count correctly. - if (status.startsWith("INSERT") || status.startsWith("UPDATE") || status.startsWith("DELETE") || status.startsWith("MOVE")) - { - update_count = Integer.parseInt(status.substring(1 + status.lastIndexOf(' '))); - } - if (status.startsWith("INSERT")) - { - insert_oid = Long.parseLong(status.substring(1 + status.indexOf(' '), - status.lastIndexOf(' '))); - } - } - catch (NumberFormatException nfe) - { - throw new PSQLException("postgresql.con.fathom", PSQLState.CONNECTION_FAILURE, status); - } - } - - /* - * Receive the field descriptions from the back end. - */ - private void receiveFieldsV3() throws SQLException - { - //TODO: use the msgSize - //TODO: use the tableOid, and tablePosition - if (fields != null) - throw new PSQLException("postgresql.con.multres", PSQLState.CONNECTION_FAILURE); - int l_msgSize = pgStream.ReceiveIntegerR(4); - int size = pgStream.ReceiveIntegerR(2); - fields = new Field[size]; - - for (int i = 0; i < fields.length; i++) - { - String typeName = pgStream.ReceiveString(connection.getEncoding()); - int tableOid = pgStream.ReceiveIntegerR(4); - int tablePosition = pgStream.ReceiveIntegerR(2); - int typeOid = pgStream.ReceiveIntegerR(4); - int typeLength = pgStream.ReceiveIntegerR(2); - int typeModifier = pgStream.ReceiveIntegerR(4); - int formatType = pgStream.ReceiveIntegerR(2); - //TODO: use the extra values coming back - fields[i] = new Field(connection, typeName, typeOid, typeLength, typeModifier); - } - } - /* - * Receive the field descriptions from the back end. - */ - private void receiveFieldsV2() throws SQLException - { - if (fields != null) - throw new PSQLException("postgresql.con.multres", PSQLState.CONNECTION_FAILURE); - - int size = pgStream.ReceiveIntegerR(2); - fields = new Field[size]; - - for (int i = 0; i < fields.length; i++) - { - String typeName = pgStream.ReceiveString(connection.getEncoding()); - int typeOid = pgStream.ReceiveIntegerR(4); - int typeLength = pgStream.ReceiveIntegerR(2); - int typeModifier = pgStream.ReceiveIntegerR(4); - fields[i] = new Field(connection, typeName, typeOid, typeLength, typeModifier); - } - } -} diff --git a/src/interfaces/jdbc/org/postgresql/core/StartupPacket.java b/src/interfaces/jdbc/org/postgresql/core/StartupPacket.java deleted file mode 100644 index a8ca7545ca8..00000000000 --- a/src/interfaces/jdbc/org/postgresql/core/StartupPacket.java +++ /dev/null @@ -1,68 +0,0 @@ -package org.postgresql.core; - -import java.io.IOException; - -/** - * Sent to the backend to initialize a newly created connection. - * - * $PostgreSQL: pgsql/src/interfaces/jdbc/org/postgresql/core/StartupPacket.java,v 1.5 2003/11/29 22:41:22 pgsql Exp $ - */ - -public class StartupPacket -{ - private static final int SM_DATABASE = 64; - private static final int SM_USER = 32; - private static final int SM_OPTIONS = 64; - private static final int SM_UNUSED = 64; - private static final int SM_TTY = 64; - - private int protocolMajor; - private int protocolMinor; - private String user; - private String database; - - public StartupPacket(int protocolMajor, int protocolMinor, String user, String database) - { - this.protocolMajor = protocolMajor; - this.protocolMinor = protocolMinor; - this.user = user; - this.database = database; - } - - public void writeTo(PGStream stream) throws IOException - { - if (protocolMajor == 3) { - v3WriteTo(stream); - } else { - v2WriteTo(stream); - } - } - - public void v3WriteTo(PGStream stream) throws IOException - { - stream.SendInteger(4 + 4 + "user".length() + 1 + user.length() + 1 + "database".length() +1 + database.length() + 1 + 1, 4); - stream.SendInteger(protocolMajor, 2); - stream.SendInteger(protocolMinor, 2); - stream.Send("user".getBytes()); - stream.SendChar(0); - stream.Send(user.getBytes()); - stream.SendChar(0); - stream.Send("database".getBytes()); - stream.SendChar(0); - stream.Send(database.getBytes()); - stream.SendChar(0); - stream.SendChar(0); - } - - public void v2WriteTo(PGStream stream) throws IOException - { - stream.SendInteger(4 + 4 + SM_DATABASE + SM_USER + SM_OPTIONS + SM_UNUSED + SM_TTY, 4); - stream.SendInteger(protocolMajor, 2); - stream.SendInteger(protocolMinor, 2); - stream.Send(database.getBytes(), SM_DATABASE); - - // This last send includes the unused fields - stream.Send(user.getBytes(), SM_USER + SM_OPTIONS + SM_UNUSED + SM_TTY); - } -} - diff --git a/src/interfaces/jdbc/org/postgresql/errors.properties b/src/interfaces/jdbc/org/postgresql/errors.properties deleted file mode 100644 index 468ef71aa8b..00000000000 --- a/src/interfaces/jdbc/org/postgresql/errors.properties +++ /dev/null @@ -1,112 +0,0 @@ -# This is the default errors -postgresql.arr.range:The array index is out of range. -postgresql.drv.version:An internal error has occured. Please recompile the driver. -postgresql.con.auth:The authentication type {0} is not supported. Check that you have configured the pg_hba.conf file to include the client's IP address or Subnet, and that it is using an authentication scheme supported by the driver. -postgresql.con.authfail:An error occured while getting the authentication request. -postgresql.con.backend:Backend start-up failed: {0} -postgresql.con.call:Callable Statements are not supported at this time. -postgresql.con.invalidchar:Invalid character data was found. This is most likely caused by stored data containing characters that are invalid for the character set the database was created in. The most common example of this is storing 8bit data in a SQL_ASCII database. -postgresql.con.closed:Connection is closed. Operation is not permitted. -postgresql.con.creobj:Failed to create object for {0} {1} -postgresql.con.failed:The connection attempt failed because {0} -postgresql.con.failed.bad.encoding:The connection attempt failed trying to get the server encoding -postgresql.con.failed.bad.autocommit:The connection attempt failed trying to get the autocommit status -postgresql.con.fathom:Unable to fathom update count {0} -postgresql.con.garbled:Garbled data received. -postgresql.con.ioerror:An IO erro occured while sending to the backend - {0} -postgresql.con.kerb4:Kerberos 4 authentication is not supported by this driver. -postgresql.con.kerb5:Kerberos 5 authentication is not supported by this driver. -postgresql.con.misc:A connection error has occurred: {0} -postgresql.con.multres:Cannot handle multiple result groups. -postgresql.con.pass:The password property is missing. It is mandatory. -postgresql.con.refused:Connection refused. Check that the hostname and port are correct and that the postmaster is accepting TCP/IP connections. -postgresql.con.scm:SCM credentials authentication is not supported by this driver. -postgresql.con.setup:Protocol error. Session setup failed. -postgresql.con.sslfail:An error occured while getting setting up the SSL connection. -postgresql.con.sslnotsupported:The server does not support SSL -postgresql.con.strobj:The object could not be stored. Check that any tables required have already been created in the database. -postgresql.con.strobjex:Failed to store object - {0} -postgresql.con.toolong:The SQL Statement is too long - {0} -postgresql.con.isolevel:Transaction isolation level {0} is not supported. -postgresql.con.tuple:Tuple received before MetaData. -postgresql.con.type:Unknown Response Type {0} -postgresql.con.user:The user property is missing. It is mandatory. -postgresql.error.detail:Detail: {0} -postgresql.error.hint:Hint: {0} -postgresql.error.position:Position: {0} -postgresql.error.where:Where: {0} -postgresql.error.location:Location: {0} -postgresql.fp.error:FastPath call returned {0} -postgresql.fp.expint:Fastpath call {0} - No result was returned and we expected an integer. -postgresql.fp.protocol:FastPath protocol error: {0} -postgresql.fp.send:Failed to send fastpath call {0} {1} -postgresql.fp.unknown:The fastpath function {0} is unknown. -postgresql.geo.box:Conversion of box failed - {0} -postgresql.geo.circle:Conversion of circle failed - {0} -postgresql.geo.line:Conversion of line failed - {0} -postgresql.geo.lseg:Conversion of lseg failed - {0} -postgresql.geo.path:Cannot tell if path is open or closed. -postgresql.geo.point:Conversion of point failed - {0} -postgresql.jvm.version:The postgresql.jar file does not contain the correct JDBC classes for this JVM. Try rebuilding. If that fails, try forcing the version supplying it to the command line using the argument -Djava.version=1.1 or -Djava.version=1.2\nException thrown was {0} -postgresql.lo.init:failed to initialise LargeObject API -postgresql.metadata.unavailable:Metadata unavailable. -postgresql.money:conversion of money failed - {0} -postgresql.noupdate:This ResultSet is not updateable. -postgresql.notsensitive:This ResultSet is not sensitive to realtime updates after the query has run. -postgresql.psqlnotimp:The backend currently does not support this feature. -postgresql.prep.is:InputStream as parameter not supported -postgresql.prep.param:No value specified for parameter {0} -postgresql.prep.range:Parameter index out of range. -postgresql.prep.type:Unknown Types value. -postgresql.res.badbigdec:Bad BigDecimal {0} -postgresql.res.badbyte:Bad Byte {0} -postgresql.res.baddate:Bad Date Format at {0} in {1} -postgresql.res.baddouble:Bad Double {0} -postgresql.res.badfloat:Bad Float {0} -postgresql.res.badint:Bad Integer {0} -postgresql.res.badlong:Bad Long {0} -postgresql.res.badshort:Bad Short {0} -postgresql.res.badtime:Bad Time {0} -postgresql.res.badtimestamp:Bad Timestamp Format at {0} in {1} -postgresql.res.closed:Result set is closed. Operation is not permitted. -postgresql.res.colname:The column name {0} not found. -postgresql.res.colrange:The column index is out of range. -postgresql.res.nextrequired:Result set not positioned properly, perhaps you need to call next(). -postgresql.serial.interface:You cannot serialize an interface. -postgresql.serial.namelength:Class & Package name length cannot be longer than 64 characters. {0} is {1} characters. -postgresql.serial.noclass:No class found for {0} -postgresql.serial.table:The table for {0} is not in the database. Contact the DBA, as the database is in an inconsistent state. -postgresql.serial.underscore:Class names may not have _ in them. You supplied {0}. -postgresql.stat.batch.error:Batch entry {0} {1} was aborted. Call getNextException() to see the cause. -postgresql.stat.noresult:No results were returned by the query. -postgresql.stat.result:A result was returned when none was expected. -postgresql.stream.eof:The backend has broken the connection. Possibly the action you have attempted has caused it to close. -postgresql.stream.flush:An I/O error has occured while flushing the output - {0} -postgresql.stream.ioerror:An I/O error occured while reading from backend - {0} -postgresql.stream.toomuch:Too much data was received. -postgresql.unusual:Something unusual has occured to cause the driver to fail. Please report this exception: {0} -postgresql.unimplemented:This method is not yet implemented. -postgresql.unexpected:An unexpected result was returned by a query. -postgresql.updateable.notupdateable: Result Set not updateable. The query that generated this result set must select only one table, and must select all primary keys from that table. See the JDBC 2.1 API Specification, section 5.6 for more details. -postgresql.updateable.oninsertrow:Can not call deleteRow() when on insert row -postgresql.updateable.emptydelete:Can't deleteRow() on empty result set -postgresql.updateable.beforestartdelete:Before start of result set. Can not call deleteRow(). -postgresql.updateable.afterlastdelete:After end of result set. Can not call deleteRow(). -postgresql.updateable.notoninsertrow:Not on insert row. -postgresql.updateable.inputstream:Input Stream is null. -postgresql.updateable.ioerror:Input Stream Error - {0} -postgresql.call.noreturntype:A CallableStatement Function was declared but no call to 'registerOutParameter (1, <some_type>)' was made. -postgresql.call.noinout:PostgreSQL only supports function return value [@ 1] (no OUT or INOUT arguments) -postgresql.call.procasfunc:This Statement [{0}] defines a procedure call (needs ?= call <stmt> to be considered a function. -postgresql.call.malformed:Malformed stmt [{0}] usage : {1} -postgresql.call.funcover:Cannot execute Query a call to setXXX (1, ..) was made where argument 1 is the return value of a function. -postgresql.call.wrongget:Parameter of type {0} was registered but call to get{1} (sqltype={2}) was made. -postgresql.call.noreturnval:A CallableStatement Function was executed with nothing returned. -postgresql.call.wrongrtntype:A CallableStatement Function was executed and the return was of type ({0}) however type={1} was registered. -postgresql.input.fetch.gt0:Fetch size must be a value greater than or equal to 0. -postgresql.input.query.gt0:Query Timeout must be a value greater than or equal to 0. -postgresql.input.rows.gt0:Maximum number of rows must be a value greater than or equal to 0. -postgresql.format.baddate:The date given: {0} does not match the format required: {1}. -postgresql.format.badtime:The time given: {0} does not match the format required: {1}. -postgresql.format.badtimestamp:The timestamp given {0} does not match the format required: {1}. -postgresql.input.field.gt0:The maximum field size must be a value greater than or equal to 0. diff --git a/src/interfaces/jdbc/org/postgresql/errors_de.properties b/src/interfaces/jdbc/org/postgresql/errors_de.properties deleted file mode 100644 index 2358000c408..00000000000 --- a/src/interfaces/jdbc/org/postgresql/errors_de.properties +++ /dev/null @@ -1,78 +0,0 @@ -# Message translation file for PostgreSQL JDBC driver -# Peter Eisentraut <[email protected]>, 2001. -# -# $PostgreSQL: pgsql/src/interfaces/jdbc/org/postgresql/errors_de.properties,v 1.6 2003/11/29 19:52:09 pgsql Exp $ - -postgresql.con.auth:Der Authentifizierungstyp �{0}� wird nicht unterst�tzt. -postgresql.con.authfail:Ein Fehler trat auf w�hrend die Authentifizierungsanfrage empfangen wurde. -postgresql.con.call:CallableStatement wird nicht unterst�tzt. -postgresql.con.creobj:Konnte Objekt vom Typ {0} nicht erstellen: {1} -postgresql.con.encoding:Nicht unterst�tzte Kodierung: {0} -postgresql.con.failed:Der Verbindungsversuch schlug fehl: {0} -postgresql.con.fathom:Kann Anzahl der ver�nderten Zeilen nicht ermitteln: {0} -postgresql.con.garbled:Unverst�ndliche Daten wurden empfangen. -postgresql.con.ioerror:Eingabe/Ausgabe-Fehler: {0} -postgresql.con.isolevel:Transaktionsisolation {0} wird nicht unterst�tzt. -postgresql.con.kerb4:Kerberos-IV-Authentifizierung wird von diesem Treiber nicht unterst�tzt. -postgresql.con.kerb5:Kerberos-V-Authentifizierung wird von diesem Treiber nicht unterst�tzt. -postgresql.con.multres:Mehrere Ergebnisgruppen k�nnen nicht verarbeitet werden. -postgresql.con.pass:Das Pa�wort fehlt. -postgresql.con.refused:Verbindung verweigert. Pr�fen Sie, da� der Server TCP/IP-Verbindungen annimmt. -postgresql.con.setup:Protokollfehler - Sitzung konnte nicht gestartet werden. -postgresql.con.strobj:Konnte Objekt nicht speichern - {0} -postgresql.con.strobjex:Das Objekt konnte nicht gespeichert werden. Pr�fen Sie, da� die ben�tigten Tabellen bereits erstellt wurden. -postgresql.con.tuple:Ergebnisdaten wurden empfangen, als sie nicht erwartet wurden. -postgresql.con.type:Unbekannte Antwort vom Server: �{0}� -postgresql.con.user:Benutzername wurde nicht angegeben. -postgresql.ds.onlyjdbc2:Es werden nur JDBC2-Verbindungen unterst�tzt. -postgresql.ds.userpswd:Kein Benutzername oder Pa�wort angegeben. -postgresql.fp.error:FastPath-Aufruf ergab �{0}�. -postgresql.fp.expint:FastPath-Aufruf �{0}� gab kein Ergebnis zur�ck, aber ein Integer wurde erwartet. -postgresql.fp.protocol:FastPath-Protokollfehler: {0} -postgresql.fp.send:Konnte FastPath-Aufruf �{0}� nicht senden: {1} -postgresql.fp.unknown:Die FastPath-Funktion �{0}� ist nicht bekannt. -postgresql.geo.box:Konnte �{0}� nicht in Typ �box� umwandeln -postgresql.geo.circle:Konnte �{0}� nicht in Typ �circle� umwandeln -postgresql.geo.line:Konnte �{0}� nicht in Typ �line� umwandeln -postgresql.geo.lseg:Konnte �{0}� nicht in Typ �lseg� umwandeln -postgresql.geo.path:Konnte nicht in Typ �path� umwandeln - konnte nicht ermitteln ob der Pfad offen oder geschlossen ist -postgresql.geo.point:Konnte �{0}� nicht in Typ �point� umwandeln -postgresql.jvm.version:Die Datei postgresql.jar enth�lt nicht die ben�tigten Klassen f�r diese JVM-Version. Versuchen Sie, den Treiber neu zu �bersetzen. Falls das nicht hilft, bestimmen Sie die Version mit den Kommandozeilenoptionen -Djava.version=1.1 oder -Djava.version=1.2. Der Fehler war �{0}� -postgresql.lo.init:Konnte Large-Object-API nicht initialisieren. -postgresql.money:Ung�ltiges Format f�r Typ �money�: {0} -postgresql.notsensitive:Dieses ResultSet erm�glicht keine Auffrischungen nach der Abfrage. -postgresql.noupdate:Dieses ResultSet kann nicht ver�ndert werden. -postgresql.prep.is:InputStream als Parameter wird nicht unterst�tzt. -postgresql.prep.param:Keinen Wert f�r Parameter {0} angegeben -postgresql.prep.range:Parameterindex au�erhalb des g�ltigen Bereichs -postgresql.prep.type:Unbekannter Zieltyp -postgresql.psqlnotimp:Der Server unterst�tzt diese Funktion nicht. -postgresql.res.badbigdec:Ung�ltiges Format f�r BigDecimal: {0} -postgresql.res.badbyte:Ung�ltiges Format f�r Byte: {0} -postgresql.res.baddate:Ung�ltiger Datumswert �{0}� -postgresql.res.baddouble:Ung�ltiges Format f�r Double: {0} -postgresql.res.badfloat:Ung�ltiges Format f�r Float: {0} -postgresql.res.badint:Ung�ltiges Format f�r Integer: {0} -postgresql.res.badlong:Ung�ltiges Format f�r Long: {0} -postgresql.res.badshort:Ung�ltiges Format f�r Short: {0} -postgresql.res.badtime:Ung�ltiger Zeitwert �{0}� -postgresql.res.badtimestamp:Ung�ltiger Wert f�r Timestamp (Datum und Zeit), in �{1}� bei Position {1} -postgresql.res.colname:Spaltenname �{0}� nicht gefunden -postgresql.res.colrange:Spaltenindex au�erhalb des g�ltigen Bereichs -postgresql.res.encoding:Nicht unterst�tzte Kodierung: {0} -postgresql.serial.interface:Ein Interface kann nicht serialisiert werden. -postgresql.serial.namelength:Klassen- und Paketname k�nnen nicht l�nger als 32 Zeichen sein. �{0}� ist {1} Zeichen lang. -postgresql.serial.noclass:Keine Klasse f�r Typ �{0}� gefunden -postgresql.serial.table:Keine Tabelle f�r Typ �{0}� in der Datenbank gefunden. Die Datenbank ist in einem unbest�ndigen Zustand. -postgresql.serial.underscore:Zu serialisierende Klassennamen d�rfen keine Unterstriche (_) enth�lten. Der angegebene Name war �{0}�. -postgresql.stat.batch.error:Batch-Anweisung Nummer {0} ({1}) wurde abgebrochen. -postgresql.stat.noresult:Die Abfrage ergab kein Ergebnis. -postgresql.stat.result:Die Anweisung ergab einen Abfrageergebnissatz, obwohl keiner erwartet wurde. -postgresql.stream.encoding:Nicht unterst�tzte Kodierung: {0} -postgresql.stream.eof:Unerwarteter Verbindungsabbruch vom Server -postgresql.stream.flush:Eingabe/Ausgabe-Fehler beim Flush zum Server: {0} -postgresql.stream.ioerror:Eingabe/Ausgabe-Fehler beim Empfang vom Server: {0} -postgresql.stream.toomuch:Zu viele Daten wurden empfangen. -postgresql.unexpected:Ein unerwartetes Resultat wurde nach einer Abfrage zur�ckgesendet. -postgresql.unimplemented:Diese Methode ist noch nicht implementiert. -postgresql.unusual:Etwas ungew�hnliches ist passiert. Bitte Teilen Sie diesem Fehler mit: {0} diff --git a/src/interfaces/jdbc/org/postgresql/errors_fr.properties b/src/interfaces/jdbc/org/postgresql/errors_fr.properties deleted file mode 100644 index 79d40e29743..00000000000 --- a/src/interfaces/jdbc/org/postgresql/errors_fr.properties +++ /dev/null @@ -1,6 +0,0 @@ -# This is the french version of some errors. Errors not in this file -# are handled by the parent errors.properties file. -postgresql.jvm.version:Le fichier de postgresql.jar ne contient pas les classes correctes de JDBC pour ce JVM. Try que rebuilding.\nException jet��es ��tait {0} -postgresql.metadata.unavailable: Les m�tadonn�es ne sont pas disponibles. -postgresql.unusual:Quelque chose de peu commun s'est produit pour faire ��chouer le gestionnaire. Veuillez enregistrer cette exception: {0} -postgresql.unimplemented:Cette m��thode n'est pas encore appliqu��e. diff --git a/src/interfaces/jdbc/org/postgresql/errors_it.properties b/src/interfaces/jdbc/org/postgresql/errors_it.properties deleted file mode 100644 index 197eac24d69..00000000000 --- a/src/interfaces/jdbc/org/postgresql/errors_it.properties +++ /dev/null @@ -1,75 +0,0 @@ -# This is the italian version of some errors. Errors not in this file -# are handled by the parent errors.properties file. -# -# Daniele Arduini <[email protected] <mailto:[email protected]>> -# Tue Aug 21 09:26:47 CEST 2001 -# -postgresql.drv.version:Si � verificato un errore interno. Si consiglia di ricompilare il driver. -postgresql.con.auth:L'autenticazione di tipo {0} non � supportata. Verificare che nel file di configurazione pg_hba.conf sia presente l'indirizzo IP o la sotto-rete del client, e che lo schema di autenticazione utilizzato sia supportato dal driver. -postgresql.con.authfail:Si � verificato un errore durante la richiesta di autenticazione. -postgresql.con.call:I ``Callable Statements'' non sono supportati al momento. -postgresql.con.creobj:Fallita la creazione dell'oggetto per {0} {1} -postgresql.con.failed:Il tentativo di connessione � fallito perch� {0} -postgresql.con.fathom:Impossibile il conteggio di ``update'' {0} -postgresql.con.garbled:Ricevuti dati incomprensibili. -postgresql.con.ioerror:Si � verificato un errore di I/O nella spedizione di dati al processo server - {0} -postgresql.con.kerb4:L'autenticazione di tipo ``Kerberos 4'' non � supportata da questo driver. -postgresql.con.kerb5:L'autenticazione di tipo ``Kerberos 5'' non � supportata da questo driver. -postgresql.con.multres:Impossibile gestire gruppi multipli di risultati. -postgresql.con.pass:La propriet� ``password'' � mancante. E` obbligatoria. -postgresql.con.refused:Connessione rifiutata. Controllare che il nome dell'host e la porta siano corretti, e che il server (postmaster) � in esecuzione con l'opzione -i, che abilita le connessioni attraverso la rete TCP/IP. -postgresql.con.setup:Errore di protocollo. Fallita l'impostazione della sessione. -postgresql.con.strobj:L'oggetto potrebbe non essere stato memorizzato. Controllare che ogni tabella richiesta � stata creata nel database. -postgresql.con.strobjex:Fallita la memorizzazione dell'oggetto - {0} -postgresql.con.toolong:L'istruzione SQL � troppo lunga - {0} -postgresql.con.isolevel:Il livello d'isolamento delle transazioni {0} non � supportato. -postgresql.con.tuple:Tupla ricevuta prima del MetaData. -postgresql.con.type:Tipo di risposta sconosciuta {0} -postgresql.con.user:La propriet� ``user'' � mancante. E` obbligatoria. -postgresql.fp.error:La chiamata a FastPath ha restituito {0} -postgresql.fp.expint:Chiamata Fastpath {0} - Nessun risultato restituito mentre ci si aspettava un intero. -postgresql.fp.protocol:Errore nel protocollo FastPath: {0} -postgresql.fp.send:Fallito l'invio della chiamata fastpath {0} {1} -postgresql.fp.unknown:La funzione fastpath {0} � sconosciuta. -postgresql.geo.box:Fallita la conversione di un ``box'' - {0} -postgresql.geo.circle:Fallita la conversione di un ``circle'' - {0} -postgresql.geo.line:Fallita la conversione di una ``line'' - {0} -postgresql.geo.lseg:Fallita la conversione di un ``lseg'' - {0} -postgresql.geo.path:Impossibile stabilire se il percorso � aperto o chiuso. -postgresql.geo.point:Fallita la conversione di un ``point'' - {0} -postgresql.jvm.version:Il file ``postgresql.jar'' non contiene le classi JDBC corrette per questa JVM. Provare a ricompilarle. Se il problema persiste, tentare di forzare la versione fornendo sulla linea di comando l'opzione -Djava.version=1.1 oppure -Djava.version=1.2\nL'eccezione ricevuta � stata {0} -postgresql.lo.init:Inizializzazione di LargeObject API fallita. -postgresql.money:Fallita la conversione di un ``money'' - {0}. -postgresql.noupdate:Questo ResultSet non � modificabile. -postgresql.notsensitive:Questo ResultSet non risente delle modifiche in tempo reale dopo che la query � stata eseguita. -postgresql.psqlnotimp:Il processo server al momento non supporta questa funzionalit�. -postgresql.prep.is:InputStream come parametro non � supportato -postgresql.prep.param:Nessun valore specificato come parametro {0}. -postgresql.prep.range:Indice del parametro fuori dall'intervallo ammissibile. -postgresql.prep.type:Valore di tipo sconosciuto. -postgresql.res.badbigdec:BigDecimal non corretto {0} -postgresql.res.badbyte:Byte non corretto {0} -postgresql.res.baddate:Date Format non corretto a {0} in {1} -postgresql.res.baddouble:Double non corretto {0} -postgresql.res.badfloat:Float non corretto {0} -postgresql.res.badint:Integer non corretto {0} -postgresql.res.badlong:Long non corretto {0} -postgresql.res.badshort:Short non corretto {0} -postgresql.res.badtime:Time non corretto {0} -postgresql.res.badtimestamp:Timestamp Format non corretto a {0} in {1} -postgresql.res.colname:Colonna denominata {0} non trovata. -postgresql.res.colrange:Indice di colonna fuori dall'intervallo ammissibile. -postgresql.serial.interface:Impossibile serializzare un'interfaccia. -postgresql.serial.namelength:La lunghezza dei nomi per Class & Package non pu� essere superiore a 32 caratteri. {0} � di {1} caratteri. -postgresql.serial.noclass:Nessuna classe trovata per {0}. -postgresql.serial.table:La tabella per {0} non � nel database. Contattare l'amministratore del DB, visto che il database � in uno stato incosistente. -postgresql.serial.underscore:Il nome di una classe non pu� contenere il carattere ``_''. E` stato fornito {0}. -postgresql.stat.batch.error:L'operazione {0} {1} della sequenza � stata annullata. -postgresql.stat.noresult:Nessun risultato � stato restituito dalla query. -postgresql.stream.eof:Il backend ha interrotto la connessione. Probabilmente la tua azione ha causato la sua uscita. -postgresql.stream.flush:Si � verificato un errore di I/O mentre si svuotava il buffer d'uscita - {0} -postgresql.stream.ioerror:Si � verificato un errore di I/O mentre si leggevano dati dal backend - {0} -postgresql.stream.toomuch:Troppi dati ricevuti. -postgresql.unusual:Qualcosa di insolito si � verificato causando il fallimento del driver. Per favore riferire all'autore del driver questa eccezione: {0} -postgresql.unimplemented:Questo metodo non � stato ancora implementato. -postgresql.unexpected:Un risultato inaspettato � stato ricevuto dalla query. diff --git a/src/interfaces/jdbc/org/postgresql/errors_nl.properties b/src/interfaces/jdbc/org/postgresql/errors_nl.properties deleted file mode 100644 index 1dc93453bcc..00000000000 --- a/src/interfaces/jdbc/org/postgresql/errors_nl.properties +++ /dev/null @@ -1,65 +0,0 @@ -# This is the default errors -# Dutch translation by Arnout Kuiper ([email protected]) -postgresql.con.auth:Het authenticatie type {0} wordt niet ondersteund. Controleer dat het IP adres of subnet van de client is geconfigureerd in de pg_hba.conf file, en dat het een authenticatie protocol gebruikt dat door de driver ondersteund wordt. -postgresql.con.authfail:Een fout trad op tijdens het ophalen van het authenticatie verzoek. -postgresql.con.call:Callable Statements worden op dit moment niet ondersteund. -postgresql.con.creobj:Kon geen object aanmaken voor {0} {1} -postgresql.con.failed:De poging om verbinding the maken faalde omdat {0} -postgresql.con.fathom:Niet in staat om the update telling te peilen {0} -postgresql.con.garbled:Verminkte data ontvangen. -postgresql.con.ioerror:Een I/O fout trad op tijdens het zenden naar de achterkant - {0} -postgresql.con.kerb4:Kerberos 4 authenticatie wordt niet ondersteund door deze driver. -postgresql.con.kerb5:Kerberos 5 authenticatie wordt niet ondersteund door deze driver. -postgresql.con.multres:Kan niet omgaan met meerdere resultaat groepen. -postgresql.con.pass:Het password, welke verplicht is, ontbreekt. -postgresql.con.refused:Verbinding geweigerd. Controleer dat de hostnaam en poort correct zijn, en dat de postmaster is opgestart met de -i vlag, welke TCP/IP networking aanzet. -postgresql.con.strobj:Het object kon niet worden opgeslagen. Controleer dat alle benodigde tabellen aangemaakt zijn in de database. -postgresql.con.strobjex:Kon niet object opslaan - {0} -postgresql.con.toolong:Het SQL Statement is te lang - {0} -postgresql.con.tuple:Tuple ontvangen voor MetaData. -postgresql.con.type:Onbekend antwoord type {0} -postgresql.con.user:De user, welke verplicht is, ontbreekt. -postgresql.fp.error:FastPath aanroep retourneerde {0} -postgresql.fp.expint:Fastpath aanroep {0} - Geen resultaat werd teruggegeven, terwijl we een integer verwacht hadden. -postgresql.fp.protocol:FastPath protocol fout: {0} -postgresql.fp.send:Kon geen fastpath aanroep verzenden {0} {1} -postgresql.fp.unknown:De fastpath functie {0} is onbekend. -postgresql.geo.box:Conversie van box faalde - {0} -postgresql.geo.circle:Conversie van circle faalde - {0} -postgresql.geo.line:Conversie van line faalde - {0} -postgresql.geo.lseg:Conversie van lseg faalde - {0} -postgresql.geo.path:Kan niet zeggen of path open of gesloten is. -postgresql.geo.point:Conversie van point faalde - {0} -postgresql.jvm.version:De postgresql.jar file bevat niet de correcte JDBC classen voor deze JVM. Probeer opnieuw te bouwen. Als dat niet werkt, probeer de versie te forceren via de command line met het argument -Djava.version=1.1 of -Djava.version=1.2\nAfgevuurde exceptie was {0} -postgresql.lo.init:Kon LargeObject API niet initialiseren -postgresql.money:Conversie van money faalde - {0}. -postgresql.prep.is:InputStream als parameter wordt niet ondersteund -postgresql.prep.param:Geen waarde opgegeven voor parameter {0}. -postgresql.prep.range:Parameterindex is buiten bereik. -postgresql.prep.type:Onbekende Types waarde. -postgresql.res.badbigdec:Foute BigDecimal {0} -postgresql.res.badbyte:Foute Byte {0} -postgresql.res.baddate:Foutief Date Formaat op {0} in {1} -postgresql.res.baddouble:Foute Double {0} -postgresql.res.badfloat:Foute Float {0} -postgresql.res.badint:Foute Integer {0} -postgresql.res.badlong:Foute Long {0} -postgresql.res.badshort:Foute Short {0} -postgresql.res.badtime:Foute Time {0} -postgresql.res.badtimestamp:Foutief Timestamp Formaat op {0} in {1} -postgresql.res.colname:De kolom naam {0} is niet gevonden. -postgresql.res.colrange:De kolom index is buiten bereik. -postgresql.serial.interface:Je can geen interface serializeren. -postgresql.serial.namelength:Class & Package name length cannot be longer than 32 characters. {0} is {1} characters. -postgresql.serial.noclass:Geen class gevonden voor {0}. -postgresql.serial.table:De tabel voor {0} is niet in de database. Neem contact op met de DBA, omdat de database in een inconsistente staat verkeert. -postgresql.serial.underscore:Class namen mogen geen _ in zich hebben. Jij voerde {0} in. -postgresql.stat.batch.error:Batch invoer {0} {1} werd afgebroken. -postgresql.stat.noresult:Geen resultaten werden teruggegeven door de query. -postgresql.stream.eof:De achterkant heeft de verbinding verbroken. Mogelijk was de actie die je probeerde de oorzaak hiervan. -postgresql.stream.flush:Een I/O fout trad op tijdens het legen van de uitvoer - {0} -postgresql.stream.ioerror:Een I/O fout trad op tijdens het lezen van de achterkant - {0} -postgresql.stream.toomuch:Teveel gegevens werden ontvangen -postgresql.unusual:Iets ongewoons is opgetreden, wat deze driver doet falen. Rapporteer deze fout AUB: {0} -postgresql.unimplemented:Deze methode is nog niet geimplementeerd -postgresql.unexpected:Een onverwacht resultaat werd teruggegeven door een query diff --git a/src/interfaces/jdbc/org/postgresql/errors_pl.properties b/src/interfaces/jdbc/org/postgresql/errors_pl.properties deleted file mode 100644 index c51c1a1b057..00000000000 --- a/src/interfaces/jdbc/org/postgresql/errors_pl.properties +++ /dev/null @@ -1,113 +0,0 @@ -# Polish translation of error messages. -# Translated by Piotr Maj <[email protected]> -postgresql.arr.range:Indeks tablicy jest poza zakresem. -postgresql.drv.version:Wyst\u0105pi\u0142 b\u0142\u0105d wewn\u0119trzny. Prosz\u0119 przekompilowa\u0107 sterownik. -postgresql.con.auth:Typ autentykacji {0} nie jest obs\u0142ugiwany. Upewnij si\u0119, \u017ce skonfigurowa\u0142e\u015b plik pg_hba.conf tak, \u017ce zawiera on adres IP lub podsie\u0107 klienta oraz \u017ce u\u017cyta metoda authentykacji jest wspierana przez ten sterownik. -postgresql.con.authfail:Wyst\u0105pi\u0142 b\u0142\u0105d podczas odbierania \u017c\u0105dania autentykacji. -postgresql.con.backend:Start serwera si\u0119 nie powi\u00f3d\u0142: {0} -postgresql.con.call:Callable Statements nie s\u0105 jeszcze obs\u0142ugiwane. -postgresql.con.invalidchar:Znaleziono nieprawid\u0142owy znak. Najprawdopodobniej jest to spowodowane przechowywaniem w bazie znak\u00f3w, kt\u00f3re nie pasuj\u0105 do zestawu znak\u00f3w wybranego podczas tworzenia bazy danych. Najcz\u0119stszy przyk\u0142ad to przechowywanie 8-bitowych znak\u00f3w w bazie o kodowaniu SQL_ASCII. -postgresql.con.closed:Po\u0142\u0105czenie jest zamkni\u0119te. Operacja nie dozwolona. -postgresql.con.creobj:Utworzenie obiektu dla {0} {1} nie powiod\u0142o si\u0119. -postgresql.con.failed:Pr\u00f3ba nawi\u0105zania po\u0142\u0105czenia nie powiod\u0142a si\u0119 z powodu: {0} -postgresql.con.failed.bad.encoding:Pr\u00f3ba nawi\u0105zania po\u0142aczenia nie powiod\u0142a si\u0119 - nie mo\u017cna uzyska\u0107 strony kodowej serwera. -postgresql.con.failed.bad.autocommit:Pr\u00f3ba nawi\u0105zania po\u0142\u0105czenia nie powiod\u0142a si\u0119 - nie mo\u017cna uzyska\u0107 statusu autocommit. -postgresql.con.fathom:Nie mo\u017cna wysondowa\u0107 ilo\u015bci rekord\u00f3w {0} -postgresql.con.garbled:Otrzymano przek\u0142amane dane. -postgresql.con.ioerror:Wyst\u0105pi\u0142 b\u0142\u0105d IO podczas wysy\u0142ania do serwera - {0} -postgresql.con.kerb4:Autentykacja Kerberos 4 nie jest wspierana przez ten sterownik. -postgresql.con.kerb5:Autentykacja 5 nie jest wspierana przez ten sterownik. -postgresql.con.misc:Wyst\u0105pi\u0142 b\u0142\u0105d po\u0142\u0105czenia: {0} -postgresql.con.multres:Nie mo\u017cna stosowa\u0107 wielokrotnych grup wynik\u00f3w. -postgresql.con.pass:Brak has\u0142a (password property). Jest to wymagane. -postgresql.con.refused:Po\u0142\u0105czenie odrzucone. Sprawd\u017a, czy prawid\u0142owo ustawi\u0142e\u015b nazw\u0119 hosta oraz port i upewnij si\u0119, czy postmaster przyjmuje po\u0142\u0105czenia TCP/IP. -postgresql.con.scm:Autentykacja SCM credentials nie jest wspierana przez ten sterownik. -postgresql.con.setup:B\u0142\u0105d protoko\u0142u. Nie uda\u0142o si\u0119 utworzy\u0107 sesji. -postgresql.con.sslfail:Wyst\u0105pi\u0142 b\u0142\u0105d podczas ustanawiania po\u0142\u0105czenia SSL. -postgresql.con.sslnotsupported:Serwer nie obs\u0142uguje SSL. -postgresql.con.strobj:Nie uda\u0142o si\u0119 zapisa\u0107 objektu. Sprawd\u017a, czy niekt\u00f3re wymagane tabele nie zosta\u0142y ju\u017c utworzone w bazie danych. -postgresql.con.strobjex:Nie uda\u0142o sie zapisa\u0107 obiektu - {0} -postgresql.con.toolong:Zapytanie SQL jest zbyt d\u0142ugie - {0} -postgresql.con.isolevel:Poziom izolacji transakcji {0} nie jest obs\u0142ugiwany. -postgresql.con.tuple:Odebrano krotk\u0119 przed MetaData. -postgresql.con.type:Nieznany typ odpowiedzi {0} -postgresql.con.user:Nie zdefiniowano u\u017cytkownika (user property). Jest to wymagane. -postgresql.error.detail:Szczeg\u00f3\u0142y: {0} -postgresql.error.hint:Wskaz\u00f3wka: {0} -postgresql.error.position:Pozycja: {0} -postgresql.error.where:Gdzie: {0} -postgresql.error.location:Lokalizacja: {0} -postgresql.fp.error:Wywo\u0142anie FastPath zwr\u00f3ci\u0142o {0} -postgresql.fp.expint:Wywo\u0142anie FastPath {0} - Nie otrzymano \u017cadnego wyniku, a oczekiwano liczby ca\u0142kowitej. -postgresql.fp.protocol:B\u0142\u0105d protoko\u0142u FastPath: {0} -postgresql.fp.send:Nie uda\u0142o si\u0119 wys\u0142a\u0107 wywo\u0142ania FastPath {0} {1} -postgresql.fp.unknown:Funkcja FastPath {0} jest nieznana. -postgresql.geo.box:Konwersja typu box nie powiod\u0142a si\u0119 - {0} -postgresql.geo.circle:Konwersja typu circle nie powiod\u0142a si\u0119 - {0} -postgresql.geo.line:Konwersja typu line nie powiod\u0142a si\u0119 - {0} -postgresql.geo.lseg:Konwersja typu lseg nie powiod\u0142a si\u0119 - {0} -postgresql.geo.path:Nie mo\u017cna stwierdzi\u0107, czy \u015bcie\u017cka jest otwarta czy zamkni\u0119ta. -postgresql.geo.point:Konwersja typu point nie powiod\u0142a si\u0119 - {0} -postgresql.jvm.version: Plik postgresql.jar nie zawiera poprawnych klas JDBC dla tej JVM. Spr\u00f3buj przekompilowa\u0107 sterownik. Je\u017celi si\u0119 to nie uda spr\u00f3buj wymusi\u0107 wersj\u0119 przez podanie jej w linii polece\u0107 jako argument -Djava.version=1.1 lub -Djava.version=1.2\nZrzucony wyj\u0105tek to {0} -postgresql.lo.init:nie uda\u0142o si\u0119 zainicjowa\u0107 LargeObject API -postgresql.metadata.unavailable:Metadata nie dost\u0119pne. -postgresql.money:Konwersja typu money nie powiod\u0142a si\u0119 - {0} -postgresql.noupdate:Ten ResultSet jest niemodyfikowalny (not updateable). -postgresql.notsensitive:Ten ResultSet nie jest wra\u017cliwy na zmiany w czasie rzeczywistym po tym, jak zapytanie si\u0119 wykona\u0142o. -postgresql.psqlnotimp:Serwer aktualnie nie obs\u0142uguje tej funkcji. -postgresql.prep.is:InputStream jako parametr nie jest obs\u0142ugiwany. -postgresql.prep.param:Nie podano warto\u015bci dla parametru {0} -postgresql.prep.range:Indeks parametru poza zakresem. -postgresql.prep.type:Nieznana warto\u015b\u0107 Types. -postgresql.res.badbigdec:Z\u0142y BigDecimal {0} -postgresql.res.badbyte:Z\u0142y Byte {0} -postgresql.res.baddate:Z\u0142y Date Format przy {0} w {1} -postgresql.res.baddouble:Z\u0142y Double {0} -postgresql.res.badfloat:Z\u0142y Float {0} -postgresql.res.badint:Z\u0142y Integer {0} -postgresql.res.badlong:Z\u0142y Long {0} -postgresql.res.badshort:Z\u0142y Short {0} -postgresql.res.badtime:Z\u0142y Time {0} -postgresql.res.badtimestamp:Z\u0142y Timestamp Format przy {0} w {1} -postgresql.res.closed:ResultSet jest zamkni\u0119ty. Operacja niedozwolona. -postgresql.res.colname:Nieznana nazwa kolumny {0}. -postgresql.res.colrange:Indeks kolumny jest poza zakresem. -postgresql.res.nextrequired:Z\u0142a pozycja w ResultSet, mo\u017ce musi\u0107 wywo\u0142a\u0107 next(). -postgresql.serial.interface:Nie mo\u017cna serializowa\u0107 interfejsu. -postgresql.serial.namelength:D\u0142ugo\u015b\u0107 nazwy klasy i pakietu nie mog\u0105 by\u0107 d\u0142u\u017csze ni\u017c 64 znaki. {0} to {1} znak\u00f3w. -postgresql.serial.noclass:Nie znaleziono klasy dla typu {0} -postgresql.serial.table:W bazie nie ma tabelu dla typu {0}. Skontaktuj si\u0119 z administratorem, poniewa\u017c baza utraci\u0142a sp\u00f3jno\u015b\u0107. -postgresql.serial.underscore:Nazwy klas nie moga zawiera\u0107 _. Wprowadzi\u0142e\u015b {0}. -postgresql.stat.batch.error:Zadanie wsadowe {0} {1} zosta\u0142o przerwane. Wywo\u0142aj getNextException(), aby pozna\u0107 przyczyn\u0119. -postgresql.stat.noresult:Zapytanie nie zwr\u00f3ci\u0142o \u017cadnych wynik\u00f3w. -postgresql.stat.result:Zwr\u00f3cono wynik zapytania, cho\u0107 nie by\u0142 on oczekiwany. -postgresql.stream.eof:Serwer zerwa\u0142 po\u0142\u0105czenie. By\u0107 mo\u017ce akcja kt\u00f3r\u0105 podj\u0105\u0142e\u015b spowodowa\u0142a, \u017ce serwer zako\u0144czy\u0142 prac\u0119. -postgresql.stream.flush:Wyst\u0105pi\u0142 b\u0142\u0105d I/O podczas opr\u00f3\u017cniania bufora wyj\u015bciowego - {0} -postgresql.stream.ioerror:Wyst\u0105pi\u0142 b\u0142\u0105d I/O podczas odczytu z serwera - {0} -postgresql.stream.toomuch:Otrzymano zbyt wiele danych. -postgresql.unusual:Co\u015b niezwyk\u0142ego spowodowa\u0142o pad sterownika. Prosz\u0119, zg\u0142o\u015b ten wyj\u0105tek: {0} -postgresql.unimplemented:Ta metoda nie jest jeszcze obs\u0142ugiwana. -postgresql.unexpected:Zapytanie zwr\u00f3ci\u0142o nieoczekiwany wynik. -postgresql.updateable.notupdateable:ResultSet nie jest modyfikowalny (not updateable). Zapytanie, kt\u00f3re zwr\u00f3ci\u0142o ten wynik musi dotyczy\u0107 tylko jednej tabeli oraz musi pobiera\u0107 wszystkie klucze g\u0142\u00f3wne tej tabeli. Zobacz Specyfikacj\u0119 JDBC 2.1 API, rozdzia\u0142 5.6, aby uzyska\u0107 wi\u0119cej szczeg\u00f3\u0142\u00f3w. -postgresql.updateable.oninsertrow:Nie mo\u017cna wywo\u0142a\u0107 deleteRow() na wstawianym rekordzie. -postgresql.updateable.emptydelete:Nie mo\u017cna wywo\u0142a\u0107 deleteRow() na pustym wyniku. -postgresql.updateable.beforestartdelete:Przed pocz\u0105tkiek ResultSet. Nie mo\u017cna wywo\u0142a\u0107 deleteRow(). -postgresql.updateable.afterlastdelete:Za ko\u0144cem ResultSet. Nie mo\u017cna wywo\u0142a\u0107 deleteRow(). -postgresql.updateable.notoninsertrow:Nie na wstawianym rekordzie. -postgresql.updateable.inputstream:Input Stream jest null. -postgresql.updateable.ioerror:B\u0142\u0105d Input Stream - {0} -postgresql.call.noreturntype:Funkcja CallableStatement zosta\u0142a zadeklarowana, ale nie wywo\u0142ano 'registerOutParameter (1, <jaki\u015b typ>)'. -postgresql.call.noinout:PostgreSQL only supports function return value [@ 1] (no OUT or INOUT arguments) -postgresql.call.procasfunc:This Statement [{0}] defines a procedure call (needs ?= call <stmt> to be considered a function. -postgresql.call.malformed:Malformed stmt [{0}] usage : {1} -postgresql.call.funcover:Cannot execute Query a call to setXXX (1, ..) was made where argument 1 is the return value of a function. -postgresql.call.wrongget:Parameter of type {0} was registered but call to get{1} (sqltype={2}) was made. -postgresql.call.noreturnval:A CallableStatement Function was executed with nothing returned. -postgresql.call.wrongrtntype:A CallableStatement Function was executed and the return was of type ({0}) however type={1} was registered. -postgresql.input.fetch.gt0:Rozmiar pobierania musi by\u0107 warto\u015bci\u0105 dodatni\u0105 lub 0. -postgresql.input.query.gt0:Timeout zapytania musi by\u0107 warto\u015bci\u0105 dodatni\u0105 lub 0. -postgresql.input.rows.gt0:Maksymalna liczba rekord\u00f3w musi by\u0107 warto\u015bci\u0105 dodatni\u0105 lub 0. -postgresql.format.baddate:Podana data: {0} nie pasuje do wymaganego formatu: {1}. -postgresql.format.badtime:Podany czas: {0} nie pasuje do wymaganego formatu: {1}. -postgresql.format.badtimestamp:Podany timestamp: {0} nie pasuje do wymaganego formatu: {1}. -postgresql.input.field.gt0:Maksymalny rozmiar pola musi by\u0107 warto\u015bci\u0105 dodatni\u0105 lub 0. diff --git a/src/interfaces/jdbc/org/postgresql/errors_pt_BR.properties b/src/interfaces/jdbc/org/postgresql/errors_pt_BR.properties deleted file mode 100644 index 984acada697..00000000000 --- a/src/interfaces/jdbc/org/postgresql/errors_pt_BR.properties +++ /dev/null @@ -1,114 +0,0 @@ -# Message translation file for PostgreSQL JDBC driver -# Euler Taveira de Oliveira <[email protected]>, 2003. -# -postgresql.arr.range:O �ndice do vetor est� fora do intervalo. -postgresql.drv.version:Um erro interno ocorreu. Por favor recompile o driver. -postgresql.con.auth:O tipo de autentica��o {0} n�o � suportado. Verifique se voc� configurou o arquivo pg_hba.conf incluindo a subrede ou endere�o IP do cliente, e se est� utilizando o esquema de autentica��o suportado pelo driver. -postgresql.con.authfail:Um erro ocorreu quando se recebia a resposta de autentica��o. -postgresql.con.backend:Inicializa��o do Backend falhou: {0} -postgresql.con.call:Instru��es execut�veis n�o s�o suportadas no momento. -postgresql.con.invalidchar:Caracter inv�lido foi encontrado. Isso � mais comumente causado por dados armazenados que cont�m caracteres que s�o inv�lidos para a codifica��o que foi criado o banco de dados. O exemplo mais comum disso � armazenar dados de 8 bits em um banco de dados SQL_ASCII. -postgresql.con.closed:Conex�o est� fechada. Opera��o n�o � permitida. -postgresql.con.creobj:Falhou ao criar objeto para {0} {1} -postgresql.con.failed:A tentativa de conex�o falhou porque {0} -postgresql.con.failed.bad.encoding:A tentativa de conex�o falhou ao receber a codifica��o do servidor -postgresql.con.failed.bad.autocommit:A tentativa de conex�o falhou ao receber o status de autocommit -postgresql.con.fathom:Imposs�vel entender contador de atualiza��o {0} -postgresql.con.garbled:Dados truncados foram recebidos. -postgresql.con.ioerror:Um erro de IO ocorreu ao enviar para o backend - {0} -postgresql.con.kerb4:Autentica��o Kerberos 4 n�o � suportada por este driver. -postgresql.con.kerb5:Autentica��o Kerberos 5 n�o � suportada por este driver. -postgresql.con.misc:Um erro de conex�o ocorreu: {0} -postgresql.con.multres:N�o pode manipular m�ltiplos grupos de resultados. -postgresql.con.pass:A propriedade senha n�o foi informada. Ela � obrigat�ria. -postgresql.con.refused:Conex�o negada. Certifique se o nome da m�quina e a porta est�o corretos e se o postmaster est� aceitando conex�es TCP/IP. -postgresql.con.scm:Autentica��o por credenciais SCM n�o � suportada por este driver. -postgresql.con.setup:Erro de protocolo. Configura��o da sess�o falhou. -postgresql.con.sslfail:Um erro ocorreu quando se estabelecia uma conex�o SSL. -postgresql.con.sslnotsupported:O servidor n�o suporta SSL -postgresql.con.strobj:O objeto n�o p�de ser armazenado. Certifique se algumas tabelas j� foram criadas no banco de dados. -postgresql.con.strobjex:Falhou ao armazenar objeto - {0} -postgresql.con.toolong:A Instru��o SQL � muito longa - {0} -postgresql.con.isolevel:N�vel de isolamento de transa��o {0} n�o � suportado. -postgresql.con.tuple:Tupla recebida antes de MetaData. -postgresql.con.type:Tipo de Resposta Desconhecido {0} -postgresql.con.user:A propriedade usu�rio n�o foi informada. Ela � obrigat�ria. -postgresql.error.detail:Detalhe: {0} -postgresql.error.hint:Dica: {0} -postgresql.error.position:Posi��o: {0} -postgresql.error.where:Onde: {0} -postgresql.error.location:Localiza��o: {0} -postgresql.fp.error:Chamada ao FastPath retornou {0} -postgresql.fp.expint:Chamada ao Fastpath {0} - Nenhum resultado foi retornado e n�s esper�vamos um inteiro. -postgresql.fp.protocol:Erro do protocolo FastPath: {0} -postgresql.fp.send:Falhou ao enviar chamada ao fastpath {0} {1} -postgresql.fp.unknown:A fun��o do fastpath {0} � desconhecida. -postgresql.geo.box:Convers�o para box falhou - {0} -postgresql.geo.circle:Convers�o para circle falhou - {0} -postgresql.geo.line:Convers�o para line falhou - {0} -postgresql.geo.lseg:Convers�o para lseg falhou - {0} -postgresql.geo.path:N�o pode dizer se caminho est� aberto ou fechado. -postgresql.geo.point:Convers�o para point falhou - {0} -postgresql.jvm.version:O arquivo postgresql.jar n�o cont�m as classes JDBC corretas para esta JVM. Tente recontru�-lo. Se falhar, tente for�ar especificando a vers�o na linha de comando utilizando o argumento -Djava.version=1.1 ou -Djava.version=1.2\nExce��o foi {0} -postgresql.lo.init:falhou ao inicializar API de Objetos Grandes -postgresql.metadata.unavailable:Metadata indispon�vel. -postgresql.money:convers�o para money falhou - {0} -postgresql.noupdate:Esse ResultSet n�o � atualiz�vel. -postgresql.notsensitive:Esse ResultSet n�o � sensitivo a atualiza��es em tempo real depois que a consulta foi executada. -postgresql.psqlnotimp:O backend atualmente n�o suporta esta caracter�stica. -postgresql.prep.is:InputStream como par�metro n�o � suportado -postgresql.prep.param:Nenhum valor especificado para o par�metro {0} -postgresql.prep.range:�ndice do par�metro fora do intervalo. -postgresql.prep.type:Valor de Tipos desconhecidos. -postgresql.res.badbigdec:BigDecimal inv�lido {0} -postgresql.res.badbyte:Byte inv�lido {0} -postgresql.res.baddate:Formato de Data inv�lido {1} {0} -postgresql.res.baddouble:Double inv�lido {0} -postgresql.res.badfloat:Float inv�lido {0} -postgresql.res.badint:Integer inv�lido {0} -postgresql.res.badlong:Long inv�lido {0} -postgresql.res.badshort:Short inv�lido {0} -postgresql.res.badtime:Time inv�lido {0} -postgresql.res.badtimestamp:Formato de Timestamp inv�lido {1} {0} -postgresql.res.closed:Conjunto de resultados est� fechado. Opera��o n�o � permitida. -postgresql.res.colname:O nome da coluna {0} n�o foi encontrado. -postgresql.res.colrange:O �ndice da coluna est� fora do intervalo. -postgresql.res.nextrequired:Conjunto de resultados n�o est� posicionado corretamente, talvez voc� precise chamar next(). -postgresql.serial.interface:Voc� n�o pode serializar uma interface. -postgresql.serial.namelength:Tamanho do nome da Classe e do Pacote n�o pode ser maior do que 64 caracteres. {0} tem {1} caracteres. -postgresql.serial.noclass:Nenhuma classe encontrada para {0} -postgresql.serial.table:A tabela para {0} n�o est� no banco de dados. Entre em contato com o DBA, e pergunte se o banco de dados n�o est� em um estado inconsistente. -postgresql.serial.underscore:Nomes das Classes n�o podem ter _. Voc� forneceu {0}. -postgresql.stat.batch.error:Entrada em lote {0} {1} foi abortada. Chame getNextException() para ver a causa. -postgresql.stat.noresult:Nenhum resultado foi retornado pela consulta. -postgresql.stat.result:Um resultado foi retornado quando nenhum era esperado. -postgresql.stream.eof:O backend fechou a conex�o. Possivelemte uma a��o que voc� executou tenha causado o fechamento. -postgresql.stream.flush:Um erro de I/O ocorreu ao liberar a sa�da - {0} -postgresql.stream.ioerror:Um erro de I/O ocorreu ao ler do backend - {0} -postgresql.stream.toomuch:Muitos dados foram recebidos. -postgresql.unusual:Alguma coisa anormal ocorreu para causar a falha do driver. Por favor reporte essa exce��o: {0} -postgresql.unimplemented:Este m�todo n�o foi implementado ainda. -postgresql.unexpected:Um resultado inesperado foi retornado pela consulta. -postgresql.updateable.notupdateable: Conjunto de Resultados n�o � atualiz�vel. A consulta que gerou esse conjunto de resultados deve selecionar somente uma tabela, e deve selecionar todas as chaves prim�rias daquela tabela. Veja a especifica��o na API do JDBC 2.1, se��o 5.6 para mais informa��o. -postgresql.updateable.oninsertrow:N�o pode chamar deleteRow() quando estiver inserindo registro -postgresql.updateable.emptydelete:N�o pode utilizar deleteRow() em um conjunto de resultados vazio -postgresql.updateable.beforestartdelete:Antes do in�cio do conjunto de resultados. N�o pode chamar deleteRow(). -postgresql.updateable.afterlastdelete:Depois do fim do conjunto de resultados. N�o pode chamar deleteRow(). -postgresql.updateable.notoninsertrow:N�o est� inserindo um registro. -postgresql.updateable.inputstream:Fluxo de Entrada � nulo. -postgresql.updateable.ioerror:Erro de Fluxo de Entrada - {0} -postgresql.call.noreturntype:Uma Instru��o Execut�vel foi declarada mas nenhuma chamada a 'registerOutParameter (1, <algum_tipo>)' foi feita. -postgresql.call.noinout:PostgreSQL s� suporta fun��o que retorna valor [@ 1] (nenhum argumento OUT ou INOUT) -postgresql.call.procasfunc:Esta Instru��o [{0}] define uma chamada a um procedimento (necessita ?= chamar <stmt> para ser considerado uma fun��o. -postgresql.call.malformed:Instru��o mal formada [{0}] uso : {1} -postgresql.call.funcover:N�o pode executar Consulta porque uma chamada a setXXX (1, ..) foi feita onde argumento 1 � o valor retornado pela fun��o. -postgresql.call.wrongget:Par�metro do tipo {0} foi registrado mas uma chamada a get{1} (tiposql={2}) foi feita. -postgresql.call.noreturnval:Uma Fun��o foi executado e nada foi retornado. -postgresql.call.wrongrtntype:Uma Fun��o foi executada e o retorno foi do tipo ({0}) contudo tipo={1} foi registrado. -postgresql.input.fetch.gt0:Tamanho da busca deve ser um valor maior ou igual a 0. -postgresql.input.query.gt0:Tempo de espera da Consulta deve ser um valor maior ou igual a 0. -postgresql.input.rows.gt0:N�mero m�ximo de linhas deve ser um valor maior ou igual a 0. -postgresql.format.baddate:A data informada: {0} n�o combina com o formato requerido: {1}. -postgresql.format.badtime:A hora informada: {0} n�o combina com o formato requerido: {1}. -postgresql.format.badtimestamp:O timestamp informado {0} n�o combina com o formato requerido: {1}. -postgresql.input.field.gt0:O tamanho m�ximo do campo deve ser um valor maior ou igual a 0. diff --git a/src/interfaces/jdbc/org/postgresql/errors_ru.properties b/src/interfaces/jdbc/org/postgresql/errors_ru.properties deleted file mode 100644 index 51271b62b36..00000000000 --- a/src/interfaces/jdbc/org/postgresql/errors_ru.properties +++ /dev/null @@ -1,118 +0,0 @@ -# errors_ru.properties -# Translation into Russian, (C) 2003 Serguei A. Mokhov, [email protected] -# -# ChangeLog: -# -# - October 12, 2003 - ... Initial translation -# -postgresql.arr.range:Индекс массива вне диапазона. -postgresql.drv.version:Внутренняя ошибка. Пожалуйста перекомпилируйте драйвер. -postgresql.con.auth:Тип аутентификации {0} не поддерживается. Проверьте что вы сконфигурировали файл pg_hba.conf чтобы включить IP адреса клиентов или подсеть. Также удостовертесь что он использует схему аутентификации поддерживаемую драйвером. -postgresql.con.authfail:Ошибка при получении запроса на аутентификацию. -postgresql.con.backend:Запуск бэкенда не удался: {0} -postgresql.con.call:Callable Statements are not supported at this time. -postgresql.con.invalidchar:Invalid character data was found. This is most likely caused by stored data containing characters that are invalid for the character set the database was created in. The most common example of this is storing 8bit data in a SQL_ASCII database. -postgresql.con.closed:Connection is closed. Operation is not permitted. -postgresql.con.creobj:Не удалось создать объект для {0} {1} -postgresql.con.failed:The connection attempt failed because {0} -postgresql.con.failed.bad.encoding:The connection attempt failed trying to get the server encoding -postgresql.con.failed.bad.autocommit:The connection attempt failed trying to get the autocommit status -postgresql.con.fathom:Unable to fathom update count {0} -postgresql.con.garbled:Garbled data received. -postgresql.con.ioerror:An IO erro occured while sending to the backend - {0} -postgresql.con.kerb4:Kerberos 4 authentication is not supported by this driver. -postgresql.con.kerb5:Kerberos 5 authentication is not supported by this driver. -postgresql.con.misc:A connection error has occurred: {0} -postgresql.con.multres:Cannot handle multiple result groups. -postgresql.con.pass:The password property is missing. It is mandatory. -postgresql.con.refused:Connection refused. Check that the hostname and port are correct and that the postmaster is accepting TCP/IP connections. -postgresql.con.scm:SCM credentials authentication is not supported by this driver. -postgresql.con.setup:Protocol error. Session setup failed. -postgresql.con.sslfail:An error occured while getting setting up the SSL connection. -postgresql.con.sslnotsupported:The server does not support SSL -postgresql.con.strobj:The object could not be stored. Check that any tables required have already been created in the database. -postgresql.con.strobjex:Failed to store object - {0} -postgresql.con.toolong:The SQL Statement is too long - {0} -postgresql.con.isolevel:Transaction isolation level {0} is not supported. -postgresql.con.tuple:Tuple received before MetaData. -postgresql.con.type:Unknown Response Type {0} -postgresql.con.user:The user property is missing. It is mandatory. -postgresql.error.detail:Подробности: {0} -postgresql.error.hint:Подсказка: {0} -postgresql.error.position:Позиция: {0} -postgresql.error.where:Где: {0} -postgresql.error.location:Местонахождение: {0} -postgresql.fp.error:FastPath call returned {0} -postgresql.fp.expint:Fastpath call {0} - No result was returned and we expected an integer. -postgresql.fp.protocol:FastPath protocol error: {0} -postgresql.fp.send:Failed to send fastpath call {0} {1} -postgresql.fp.unknown:The fastpath function {0} is unknown. -postgresql.geo.box:Conversion of box failed - {0} -postgresql.geo.circle:Conversion of circle failed - {0} -postgresql.geo.line:Conversion of line failed - {0} -postgresql.geo.lseg:Conversion of lseg failed - {0} -postgresql.geo.path:Cannot tell if path is open or closed. -postgresql.geo.point:Conversion of point failed - {0} -postgresql.jvm.version:The postgresql.jar file does not contain the correct JDBC classes for this JVM. Try rebuilding. If that fails, try forcing the version supplying it to the command line using the argument -Djava.version=1.1 or -Djava.version=1.2\nException thrown was {0} -postgresql.lo.init:failed to initialise LargeObject API -postgresql.metadata.unavailable:Metadata unavailable. -postgresql.money:conversion of money failed - {0} -postgresql.noupdate:This ResultSet is not updateable. -postgresql.notsensitive:This ResultSet is not sensitive to realtime updates after the query has run. -postgresql.psqlnotimp:The backend currently does not support this feature. -postgresql.prep.is:InputStream as parameter not supported -postgresql.prep.param:No value specified for parameter {0} -postgresql.prep.range:Parameter index out of range. -postgresql.prep.type:Unknown Types value. -postgresql.res.badbigdec:Bad BigDecimal {0} -postgresql.res.badbyte:Плохой Byte {0} -postgresql.res.baddate:Bad Date Format at {0} in {1} -postgresql.res.baddouble:Плохой Double {0} -postgresql.res.badfloat:Плохой Float {0} -postgresql.res.badint:Плохой Integer {0} -postgresql.res.badlong:Плохой Long {0} -postgresql.res.badshort:Плохой Short {0} -postgresql.res.badtime:Bad Time {0} -postgresql.res.badtimestamp:Bad Timestamp Format at {0} in {1} -postgresql.res.closed:Result set is closed. Operation is not permitted. -postgresql.res.colname:The column name {0} not found. -postgresql.res.colrange:Индекс колонки вне диапазона. -postgresql.res.nextrequired:Result set not positioned properly, perhaps you need to call next(). -postgresql.serial.interface:Нельзя сериализовать интерфейс. -postgresql.serial.namelength:Class & Package name length cannot be longer than 64 characters. {0} is {1} characters. -postgresql.serial.noclass:Класс не найден для {0} -postgresql.serial.table:The table for {0} is not in the database. Contact the DBA, as the database is in an inconsistent state. -postgresql.serial.underscore:Class names may not have _ in them. You supplied {0}. -postgresql.stat.batch.error:Batch entry {0} {1} was aborted. Call getNextException() to see the cause. -postgresql.stat.noresult:No results were returned by the query. -postgresql.stat.result:A result was returned when none was expected. -postgresql.stream.eof:The backend has broken the connection. Possibly the action you have attempted has caused it to close. -postgresql.stream.flush:An I/O error has occured while flushing the output - {0} -postgresql.stream.ioerror:An I/O error occured while reading from backend - {0} -postgresql.stream.toomuch:Too much data was received. -postgresql.unusual:Something unusual has occured to cause the driver to fail. Please report this exception: {0} -postgresql.unimplemented:This method is not yet implemented. -postgresql.unexpected:An unexpected result was returned by a query. -postgresql.updateable.notupdateable: Result Set not updateable. The query that generated this result set must select only one table, and must select all primary keys from that table. See the JDBC 2.1 API Specification, section 5.6 for more details. -postgresql.updateable.oninsertrow:Can not call deleteRow() when on insert row -postgresql.updateable.emptydelete:Can't deleteRow() on empty result set -postgresql.updateable.beforestartdelete:Before start of result set. Can not call deleteRow(). -postgresql.updateable.afterlastdelete:After end of result set. Can not call deleteRow(). -postgresql.updateable.notoninsertrow:Not on insert row. -postgresql.updateable.inputstream:Input Stream is null. -postgresql.updateable.ioerror:ошибка Input Stream - {0} -postgresql.call.noreturntype:A CallableStatement Function was declared but no call to 'registerOutParameter (1, <some_type>)' was made. -postgresql.call.noinout:PostgreSQL only supports function return value [@ 1] (no OUT or INOUT arguments) -postgresql.call.procasfunc:This Statement [{0}] defines a procedure call (needs ?= call <stmt> to be considered a function. -postgresql.call.malformed:Malformed stmt [{0}] usage : {1} -postgresql.call.funcover:Cannot execute Query a call to setXXX (1, ..) was made where argument 1 is the return value of a function. -postgresql.call.wrongget:Parameter of type {0} was registered but call to get{1} (sqltype={2}) was made. -postgresql.call.noreturnval:A CallableStatement Function was executed with nothing returned. -postgresql.call.wrongrtntype:A CallableStatement Function was executed and the return was of type ({0}) however type={1} was registered. -postgresql.input.fetch.gt0:Fetch size must be a value greater than or equal to 0. -postgresql.input.query.gt0:Query Timeout must be a value greater than or equal to 0. -postgresql.input.rows.gt0:Maximum number of rows must be a value greater than or equal to 0. -postgresql.format.baddate:The date given: {0} does not match the format required: {1}. -postgresql.format.badtime:The time given: {0} does not match the format required: {1}. -postgresql.format.badtimestamp:The timestamp given {0} does not match the format required: {1}. -postgresql.input.field.gt0:The maximum field size must be a value greater than or equal to 0. diff --git a/src/interfaces/jdbc/org/postgresql/errors_zh_TW.properties b/src/interfaces/jdbc/org/postgresql/errors_zh_TW.properties deleted file mode 100644 index eed4a40e86c..00000000000 --- a/src/interfaces/jdbc/org/postgresql/errors_zh_TW.properties +++ /dev/null @@ -1,112 +0,0 @@ -# 2003-11-25 Zhenbang Wei <[email protected]> -postgresql.arr.range:\u9663\u5217\u7d22\u5f15\u8d85\u904e\u8a31\u53ef\u7bc4\u570d\u3002 -postgresql.drv.version:\u767c\u751f\u5167\u90e8\u932f\u8aa4\uff0c\u8acb\u91cd\u65b0\u7de8\u8b6f\u9a45\u52d5\u7a0b\u5f0f\u3002 -postgresql.con.auth:\u4e0d\u652f\u63f4{0}\u8a8d\u8b49\uff0c\u8acb\u78ba\u5b9a\u60a8\u5df2\u7d93\u5c07\u5ba2\u6236\u7aef\u7684IP\u4f4d\u5740\u6216\u7db2\u8def\u5340\u6bb5\u4ee5\u53ca\u9a45\u52d5\u7a0b\u5f0f\u6240\u652f\u63f4\u7684\u8a8d\u8b49\u985e\u578b\u52a0\u5165pg_hba.conf\u3002 -postgresql.con.authfail:\u8b80\u53d6\u8a8d\u8b49\u8acb\u6c42\u6642\u767c\u751f\u932f\u8aa4\u3002 -postgresql.con.backend:\u5f8c\u7aef\u555f\u52d5\u5931\u6557\uff1a{0} -postgresql.con.call:\u76ee\u524d\u4e0d\u652f\u63f4CallableStatement\u3002 -postgresql.con.invalidchar:\u767c\u73fe\u4e0d\u5408\u6cd5\u7684\u5b57\u5143\uff0c\u53ef\u80fd\u7684\u539f\u56e0\u662f\u6b32\u5132\u5b58\u7684\u8cc7\u6599\u4e2d\u5305\u542b\u8cc7\u6599\u5eab\u7684\u5b57\u5143\u96c6\u4e0d\u652f\u63f4\u7684\u5b57\u78bc\uff0c\u5176\u4e2d\u6700\u5e38\u898b\u4f8b\u5b50\u7684\u5c31\u662f\u5c078\u4f4d\u5143\u8cc7\u6599\u5b58\u5165\u4f7f\u7528SQL_ASCII\u7684\u8cc7\u6599\u5eab\u3002 -postgresql.con.closed:\u9023\u7dda\u5df2\u95dc\u9589\uff0c\u4e0d\u5141\u8a31\u64cd\u4f5c\u3002 -postgresql.con.creobj:\u70ba{0} {1}\u5efa\u7acb\u7269\u4ef6\u5931\u6557 -postgresql.con.failed:\u9023\u7dda\u5931\u6557\uff0c\u56e0\u70ba{0} -postgresql.con.failed.bad.encofing:\u9023\u7dda\u5931\u6557\uff0c\u7121\u6cd5\u53d6\u5f97\u4f3a\u670d\u5668\u4f7f\u7528\u7684\u7de8\u78bc -postgresql.con.failed.bad.autocommit:\u9023\u7dda\u5931\u6557\uff0c\u7121\u6cd5\u53d6\u5f97autocommit\u72c0\u614b -postgresql.con.fathom:\u7121\u6cd5\u53d6\u5f97\u66f4\u65b0\u7684\u8cc7\u6599\u7b46\u6578{0} -postgresql.con.garbled:\u6536\u5230\u7121\u6548\u7684\u8cc7\u6599\u3002 -postgresql.con.ioerror:\u50b3\u9001\u8cc7\u6599\u81f3\u5f8c\u7aef\u6642\u767c\u751fIO\u932f\u8aa4 - {0} -postgresql.con.kerb4:\u9a45\u52d5\u7a0b\u5f0f\u4e0d\u652f\u63f4Kerberos 4\u8a8d\u8b49\u3002 -postgresql.con.kerb5:\u9a45\u52d5\u7a0b\u5f0f\u4e0d\u652f\u63f4Kerberos 5\u8a8d\u8b49\u3002 -postgresql.con.misc:\u767c\u751f\u9023\u7dda\u932f\u8aa4\uff1a{0} -postgresql.con.multres:\u7121\u6cd5\u8655\u7406\u591a\u91cd\u67e5\u8a62\u7d50\u679c\u3002 -postgresql.con.pass:\u6c92\u6709password\u5c6c\u6027\uff0c\u9019\u9805\u5c6c\u6027\u662f\u5fc5\u9700\u7684\u3002 -postgresql.con.refused:\u62d2\u7d55\u9023\u7dda\uff0c\u8acb\u6aa2\u67e5\u4e3b\u6a5f\u540d\u7a31\u548c\u57e0\u865f\uff0c\u4e26\u78ba\u5b9apostmaster\u555f\u52d5\u6642\u4f7f\u7528\u4e86-i\u53c3\u6578\u958b\u555fTCP/IP\u7db2\u8def\u529f\u80fd\u3002 -postgresql.con.scm:\u9a45\u52d5\u7a0b\u5f0f\u4e0d\u652f\u63f4SCM\u8a8d\u8b49\u3002 -postgresql.con.setup:\u901a\u8a0a\u5354\u5b9a\u932f\u8aa4\uff0cSession\u521d\u59cb\u5316\u5931\u6557\u3002 -postgresql.con.sslfail:\u9032\u884cSSL\u9023\u7dda\u6642\u767c\u751f\u932f\u8aa4\u3002 -postgresql.con.sslnotsupported:\u4f3a\u670d\u5668\u4e0d\u652f\u63f4SSL\u9023\u7dda\u3002 -postgresql.con.strobj:\u7121\u6cd5\u5132\u5b58\u7269\u4ef6\uff0c\u8acb\u78ba\u5b9a\u5df2\u7d93\u5728\u8cc7\u6599\u5eab\u4e2d\u5efa\u7acb\u8981\u4f7f\u7528\u7684\u8cc7\u6599\u8868\u3002 -postgresql.con.strobjex:\u5132\u5b58\u7269\u4ef6\u5931\u6557 - {0} -postgresql.con.toolong:SQL \u6558\u8ff0\u904e\u9577 - {0} -postgresql.con.isolevel:\u4e0d\u652f\u63f4\u4ea4\u6613\u9694\u7d55\u7b49\u7d1a{0}\u3002 -postgresql.con.tuple:Tuple\u5728MetaData\u4e4b\u524d\u50b3\u56de\u3002 -postgresql.con.type:\u4e0d\u660e\u7684\u56de\u61c9\u985e\u578b{0} -postgresql.con.user:\u6c92\u6709user\u5c6c\u6027\uff0c\u9019\u9805\u5c6c\u6027\u662f\u5fc5\u9700\u7684\u3002 -postgresql.error.detail:Detail: {0} -postgresql.error.hint:Hint: {0} -postgresql.error.position:Position: {0} -postgresql.error.where:Where: {0} -postgresql.error.location:Location: {0} -postgresql.fp.error:FastPath\u547c\u53eb\u50b3\u56de{0} -postgresql.fp.expint:Fastpath\u547c\u53eb{0} - \u6c92\u6709\u50b3\u56de\u503c\uff0c\u61c9\u8a72\u50b3\u56de\u4e00\u500b\u6574\u6578\u3002 -postgresql.fp.protocol:FastPath\u5354\u5b9a\u932f\u8aa4\uff1a{0} -postgresql.fp.send:\u50b3\u9001fastpath\u547c\u53eb{0} {1}\u5931\u6557 -postgresql.fp.unknown:\u4e0d\u660e\u7684fastpath\u51fd\u5f0f{0}\u3002 -postgresql.geo.box:\u8f49\u63dbbox\u5931\u6557 - {0} -postgresql.geo.circle:\u8f49\u63dbcircle\u5931\u6557 - {0} -postgresql.geo.line:\u8f49\u63dbline\u5931\u6557 - {0} -postgresql.geo.lseg:\u8f49\u63dblseg\u5931\u6557 - {0} -postgresql.geo.path:\u7121\u6cd5\u5f97\u77e5path\u662f\u95dc\u9589\u6216\u958b\u555f\u3002 -postgresql.geo.point:\u8f49\u63dbpoint\u5931\u6557 - {0} -postgresql.jvm.version:\u5728postgresql.jar\u4e2d\u627e\u4e0d\u5230\u6b63\u78ba\u7684JDBC\u985e\u5225\u4f9bJVM\u4f7f\u7528\uff0c\u8acb\u91cd\u65b0\u7de8\u8b6f\uff0c\u5982\u679c\u4ecd\u7136\u767c\u751f\u932f\u8aa4\uff0c\u8acb\u5728\u57f7\u884c\u6642\u7528-Djava.version=1.1\u6216-Djava.version=1.2\u5f37\u5236\u6307\u5b9a\u7248\u672c\n\u7522\u751f\u7684\u4f8b\u5916\u662f{0} -postgresql.lo.init:\u521d\u59cb\u5316LargeObject API\u5931\u6557\u3002 -postgresql.metadata.unavailable:\u7121\u6cd5\u53d6\u5f97Metadata\u3002 -postgresql.money:\u8f49\u63dbmoney\u5931\u6557 - {0}\u3002 -postgresql.noupdate:\u67e5\u8a62\u7d50\u679c\u4e0d\u53ef\u66f4\u65b0\u3002 -postgresql.notsensitive:\u67e5\u8a62\u7d50\u679c\u4e0d\u80fd\u5373\u6642\u53cd\u6620\u8b8a\u52d5\u7684\u8cc7\u6599\u3002 -postgresql.psqlnotimp:\u5f8c\u7aef\u76ee\u524d\u4e0d\u652f\u63f4\u9019\u9805\u529f\u80fd\u3002 -postgresql.prep.is:\u4e0d\u652f\u63f4\u4ee5InputStream\u505a\u70ba\u53c3\u6578\u3002 -postgresql.prep.param:\u672a\u8a2d\u5b9a\u53c3\u6578{0}\u7684\u5167\u5bb9\u3002 -postgresql.prep.range:\u53c3\u6578\u7d22\u5f15\u8d85\u904e\u8a31\u53ef\u7bc4\u570d\u3002 -postgresql.prep.type:\u4e0d\u660e\u7684\u578b\u5225\u3002 -postgresql.res.badbigdec:\u932f\u8aa4\u7684BigDecimal {0} -postgresql.res.badbyte:\u932f\u8aa4\u7684Byte {0} -postgresql.res.baddate:\u932f\u8aa4\u7684Date\u683c\u5f0f {1} \u65bc {0} -postgresql.res.baddouble:\u932f\u8aa4\u7684Double {0} -postgresql.res.badfloat:\u932f\u8aa4\u7684Float {0} -postgresql.res.badint:\u932f\u8aa4\u7684Integer {0} -postgresql.res.badlong:\u932f\u8aa4\u7684Long {0} -postgresql.res.badshort:\u932f\u8aa4\u7684Short {0} -postgresql.res.badtime:\u932f\u8aa4\u7684Time {0} -postgresql.res.badtimestamp:\u932f\u8aa4\u7684Timestamp\u683c\u5f0f{1}\u65bc{0} -postgresql.res.closed:ResultSet\u5df2\u7d93\u95dc\u9589\uff0c\u4e0d\u5141\u8a31\u5176\u5b83\u64cd\u4f5c\u3002 -postgresql.res.colname:\u627e\u4e0d\u5230\u6b04\u4f4d\u540d\u7a31{0}\u3002 -postgresql.res.colrange:\u6b04\u4f4d\u7d22\u5f15\u8d85\u904e\u8a31\u53ef\u7bc4\u570d\u3002 -postgresql.res.nextrequired:\u67e5\u8a62\u7d50\u679c\u6307\u6a19\u4f4d\u7f6e\u4e0d\u6b63\u78ba\uff0c\u60a8\u4e5f\u8a31\u9700\u8981\u547c\u53ebResultSet\u7684next()\u65b9\u6cd5\u3002 -postgresql.serial.interface:\u4e0d\u5141\u8a31\u5c07\u4ecb\u9762\u5e8f\u5217\u5316\u3002 -postgresql.serial.namelength:\u985e\u5225\u548c\u5305\u88dd\u7684\u540d\u7a31\uff0c\u9577\u5ea6\u4e0d\u80fd\u8d85\u904e32\u5b57\u5143\uff0c{0}\u7684\u9577\u5ea6\u662f{1}\u5b57\u5143\u3002 -postgresql.serial.noclass:\u627e\u4e0d\u5230\u985e\u5225{0}\u3002 -postgresql.serial.table:\u8655\u7406{0}\u6642\u627e\u4e0d\u5230\u8cc7\u6599\u8868\uff0c\u8cc7\u6599\u5eab\u72c0\u614b\u4e0d\u6b63\u5e38\uff0c\u8acb\u806f\u7d61DBA\u8655\u7406\u3002 -postgresql.serial.underscore:\u985e\u5225\u540d\u7a31\u4e0d\u80fd\u4f7f\u7528_\u5b57\u5143\uff0c\u60a8\u6240\u7528\u7684\u540d\u7a31\u662f{0}\u3002 -postgresql.stat.batch.error:\u6279\u6b21\u8655\u7406\u5ffd\u7565{0} {1}\u3002 -postgresql.stat.noresult:\u6c92\u6709\u50b3\u56de\u4efb\u4f55\u67e5\u8a62\u7d50\u679c\u3002 -postgresql.stat.result:\u50b3\u56de\u9810\u671f\u5916\u7684\u7d50\u679c\u3002 -postgresql.stream.eof:\u5f8c\u7aef\u7d50\u675f\u9023\u7dda\uff0c\u4e5f\u8a31\u662f\u56e0\u70ba\u60a8\u6240\u57f7\u884c\u7684\u52d5\u4f5c\u5c0e\u81f4\u9023\u7dda\u4e2d\u65b7\u3002 -postgresql.stream.flush:\u9001\u51fa\u8cc7\u6599\u6642\u767c\u751fI/O\u932f\u8aa4 - {0} -postgresql.stream.ioerror:\u5f9e\u5f8c\u7aef\u8b80\u53d6\u8cc7\u6599\u6642\u767c\u751fI/O\u932f\u8aa4 - {0} -postgresql.stream.toomuch:\u63a5\u6536\u904e\u591a\u8cc7\u6599\u3002 -postgresql.unusual:\u4e0d\u660e\u7684\u539f\u56e0\u5c0e\u81f4\u9a45\u52d5\u7a0b\u5f0f\u767c\u751f\u932f\u8aa4\uff0c\u8acb\u56de\u5831\u9019\u500b\u4f8b\u5916\uff1a{0} -postgresql.unimplemented:\u9019\u500b\u65b9\u6cd5\u5c1a\u672a\u5be6\u4f5c\u3002 -postgresql.unexpected:\u50b3\u56de\u975e\u9810\u671f\u7684\u67e5\u8a62\u7d50\u679c\u3002 -postgresql.updateable.notupdateable:\u4e0d\u53ef\u66f4\u65b0\u7684ResultSet\u3002\u7528\u4f86\u7522\u751f\u9019\u500bResultSet\u7684SQL\u6307\u4ee4\u53ea\u80fd\u64cd\u4f5c\u4e00\u500b\u8cc7\u6599\u8868\uff0c\u4e26\u4e14\u5fc5\u9700\u9078\u64c7\u4e3b\u9375\u6b04\u4f4d\uff0c\u8acb\u53c3\u95b1JDBC 2.1 API\u898f\u683c\u66f85.6\u7bc0\u3002 -postgresql.updateable.oninsertrow:\u6b63\u5728\u65b0\u589e\u4e00\u7b46\u8cc7\u6599\u6642\u4e0d\u884c\u547c\u53ebdeleteRow()\u65b9\u6cd5\u3002 -postgresql.updateable.emptydelete:\u4e0d\u884c\u5728\u7a7a\u7684ResultSet\u4f7f\u7528deleteRow()\u65b9\u6cd5\u3002 -postgresql.updateable.beforestartdelete:\u4e0d\u884c\u5728ResultSet\u7684\u7b2c\u4e00\u7b46\u8cc7\u6599\u4e4b\u524d\u547c\u53ebdeleteRow()\u65b9\u6cd5\u3002 -postgresql.updateable.afterlastdelete:\u4e0d\u884c\u5728ResultSet\u7684\u6700\u5f8c\u4e00\u7b46\u8cc7\u6599\u4e4b\u5f8c\u547c\u53ebdeleteRow()\u65b9\u6cd5\u3002 -postgresql.updateable.notoninsertrow:\u4e0d\u5728\u65b0\u589e\u7684\u8cc7\u6599\u5217\u4e0a\u3002 -postgresql.updateable.inputstream:InputStream\u662fnull\u3002 -postgresql.updateable.ioerror:InputStream\u932f\u8aa4\u3002 -postgresql.call.noreturntype:\u5df2\u7d93\u5ba3\u544aCallableStatement\u51fd\u5f0f\uff0c\u4f46\u662f\u5c1a\u672a\u547c\u53eb'registerOutParameter (1, <some_type>)'\u3002 -postgresql.call.noinout:PostgreSQL\u53ea\u652f\u63f4\u50b3\u56de\u503c\u70ba[@ 1]\u7684\u51fd\u5f0f(\u6c92\u6709OUT\u6216INPUT\u5f15\u6578)\u3002 -postgresql.call.procasfunc:\u6558\u8ff0[{0}]\u5b9a\u7fa9\u4e86\u4e00\u500b\u9810\u5132\u7a0b\u5e8f(\u547c\u53eb\u51fd\u5f0f\u9700\u8981\u4f7f\u7528?= call <stmt>\u683c\u5f0f)\u3002 -postgresql.call.malformed:\u932f\u8aa4\u7684\u6558\u8ff0[{0}]\u7528\u6cd5\uff1a{1} -postgresql.call.funcover:\u7121\u6cd5\u57f7\u884c\u67e5\u8a62\uff0c\u547c\u53eb\u4e86setXXX(1, ..)\uff0c\u4f46\u662f\u7b2c\u4e00\u500b\u5f15\u6578\u662f\u51fd\u5f0f\u7684\u50b3\u56de\u503c\u3002 -postgresql.call.wrongget:\u5df2\u8a3b\u518a\u53c3\u6578\u578b\u5225{0}\uff0c\u4f46\u662f\u53c8\u547c\u53eb\u4e86get{1}(sqltype={2})\u3002 -postgresql.call.noreturnval:CallableStatement\u57f7\u884c\u51fd\u5f0f\u5f8c\u6c92\u6709\u50b3\u56de\u503c\u3002 -postgresql.call.wrongrtntype:CallableStatement\u57f7\u884c\u51fd\u5f0f\u5f8c\u50b3\u56de\u503c\u7684\u578b\u5225\u662f{0}\uff0c\u4f46\u662f\u8a3b\u518a\u7684\u578b\u5225\u662f{1}\u3002 -postgresql.input.fetch.gt0:\u8cc7\u6599\u8b80\u53d6\u7b46\u6578(fetch size)\u5fc5\u9808\u5927\u65bc\u6216\u7b49\u65bc0\u3002 -postgresql.input.query.gt0:\u67e5\u8a62\u903e\u6642\u7b49\u5019\u6642\u9593\u5fc5\u9808\u5927\u65bc\u6216\u7b49\u65bc0\u3002 -postgresql.input.rows.gt0:\u6700\u5927\u8cc7\u6599\u8b80\u53d6\u7b46\u6578\u5fc5\u9808\u5927\u65bc\u6216\u7b49\u65bc0\u3002 -postgresql.format.baddate:\u50b3\u5165\u7684\u65e5\u671f{0}\u8207\u8981\u6c42\u7684\u683c\u5f0f{1}\u4e0d\u7b26\u3002 -postgresql.format.badtime:\u50b3\u5165\u7684\u6642\u9593{0}\u8207\u8981\u6c42\u7684\u683c\u5f0f{1}\u4e0d\u7b26\u3002 -postgresql.format.badtimestamp:\u50b3\u5165\u7684\u6642\u9593\u6233\u8a18{0}\u8207\u8981\u6c42\u7684\u683c\u5f0f{1}\u4e0d\u7b26\u3002 -postgresql.input.field.gt0:\u6700\u5927\u6b04\u4f4d\u5bb9\u91cf\u5fc5\u9808\u5927\u65bc\u6216\u7b49\u65bc0\u3002 diff --git a/src/interfaces/jdbc/org/postgresql/fastpath/Fastpath.java b/src/interfaces/jdbc/org/postgresql/fastpath/Fastpath.java deleted file mode 100644 index e8836152650..00000000000 --- a/src/interfaces/jdbc/org/postgresql/fastpath/Fastpath.java +++ /dev/null @@ -1,430 +0,0 @@ -/*------------------------------------------------------------------------- - * - * Fastpath.java - * This class implements the Fastpath api. - * - * Copyright (c) 2003, PostgreSQL Global Development Group - * - * IDENTIFICATION - * $PostgreSQL: pgsql/src/interfaces/jdbc/org/postgresql/fastpath/Fastpath.java,v 1.20 2003/12/18 03:27:14 davec Exp $ - * - *------------------------------------------------------------------------- - */ -package org.postgresql.fastpath; - -import java.io.IOException; -import java.sql.SQLException; -import java.sql.ResultSet; -import java.util.Hashtable; -import org.postgresql.Driver; -import org.postgresql.core.BaseConnection; -import org.postgresql.core.PGStream; -import org.postgresql.util.PSQLException; -import org.postgresql.util.PSQLState; - -/* - * This class implements the Fastpath api. - * - * <p>This is a means of executing functions imbeded in the org.postgresql - * backend from within a java application. - * - * <p>It is based around the file src/interfaces/libpq/fe-exec.c - * - */ -public class Fastpath -{ - // This maps the functions names to their id's (possible unique just - // to a connection). - protected Hashtable func = new Hashtable(); - - protected BaseConnection conn; // our connection - protected PGStream stream; // the network stream - - /* - * Initialises the fastpath system - * - * @param conn BaseConnection to attach to - * @param stream The network stream to the backend - */ - public Fastpath(BaseConnection conn, PGStream stream) - { - this.conn = conn; - this.stream = stream; - } - - /* - * Send a function call to the PostgreSQL backend - * - * @param fnid Function id - * @param resulttype True if the result is an integer, false for other results - * @param args FastpathArguments to pass to fastpath - * @return null if no data, Integer if an integer result, or byte[] otherwise - * @exception SQLException if a database-access error occurs. - */ - public Object fastpath(int fnid, boolean resulttype, FastpathArg[] args) throws SQLException - { - if (conn.getPGProtocolVersionMajor() == 3) { - return fastpathV3(fnid, resulttype, args); - } else { - return fastpathV2(fnid, resulttype, args); - } - } - - private Object fastpathV3(int fnid, boolean resulttype, FastpathArg[] args) throws SQLException - { - // added Oct 7 1998 to give us thread safety - synchronized (stream) - { - // send the function call - try - { - int l_msgLen = 0; - l_msgLen += 16; - for (int i=0;i < args.length;i++) - l_msgLen += args[i].sendSize(); - - stream.SendChar('F'); - stream.SendInteger(l_msgLen,4); - stream.SendInteger(fnid, 4); - stream.SendInteger(1,2); - stream.SendInteger(1,2); - stream.SendInteger(args.length,2); - - for (int i = 0;i < args.length;i++) - args[i].send(stream); - - stream.SendInteger(1,2); - - // This is needed, otherwise data can be lost - stream.flush(); - - } - catch (IOException ioe) - { - throw new PSQLException("postgresql.fp.send", PSQLState.COMMUNICATION_ERROR, new Integer(fnid), ioe); - } - - // Now handle the result - - // Now loop, reading the results - Object result = null; // our result - PSQLException error = null; - int c; - boolean l_endQuery = false; - while (!l_endQuery) - { - c = stream.ReceiveChar(); - - switch (c) - { - case 'A': // Asynchronous Notify - int pid = stream.ReceiveInteger(4); - String msg = stream.ReceiveString(conn.getEncoding()); - conn.addNotification(new org.postgresql.core.Notification(msg, pid)); - break; - //------------------------------ - // Error message returned - case 'E': - int l_elen = stream.ReceiveIntegerR(4); - String totalMessage = conn.getEncoding().decode(stream.Receive(l_elen-4)); - PSQLException l_error = PSQLException.parseServerError(totalMessage); - - if (error != null) { - error.setNextException(l_error); - } else { - error = l_error; - } - - break; - //------------------------------ - // Notice from backend - case 'N': - int l_nlen = stream.ReceiveIntegerR(4); - conn.addWarning(conn.getEncoding().decode(stream.Receive(l_nlen-4))); - break; - - case 'V': - int l_msgLen = stream.ReceiveIntegerR(4); - int l_valueLen = stream.ReceiveIntegerR(4); - - if (l_valueLen == -1) - { - //null value - } - else if (l_valueLen == 0) - { - result = new byte[0]; - } - else - { - // Return an Integer if - if (resulttype) - result = new Integer(stream.ReceiveIntegerR(l_valueLen)); - else - { - byte buf[] = new byte[l_valueLen]; - stream.Receive(buf, 0, l_valueLen); - result = buf; - } - } - break; - - case 'Z': - //TODO: use size better - if (stream.ReceiveIntegerR(4) != 5) throw new PSQLException("postgresql.con.setup", PSQLState.CONNECTION_UNABLE_TO_CONNECT); - //TODO: handle transaction status - char l_tStatus = (char)stream.ReceiveChar(); - l_endQuery = true; - break; - - default: - throw new PSQLException("postgresql.fp.protocol", PSQLState.COMMUNICATION_ERROR, new Character((char)c)); - } - } - - if ( error != null ) - throw error; - - return result; - } - } - - private Object fastpathV2(int fnid, boolean resulttype, FastpathArg[] args) throws SQLException - { - // added Oct 7 1998 to give us thread safety - synchronized (stream) - { - // send the function call - try - { - // 70 is 'F' in ASCII. Note: don't use SendChar() here as it adds padding - // that confuses the backend. The 0 terminates the command line. - stream.SendInteger(70, 1); - stream.SendInteger(0, 1); - - stream.SendInteger(fnid, 4); - stream.SendInteger(args.length, 4); - - for (int i = 0;i < args.length;i++) - args[i].send(stream); - - // This is needed, otherwise data can be lost - stream.flush(); - - } - catch (IOException ioe) - { - //Should be sending exception as second arg. - throw new PSQLException("postgresql.fp.send", PSQLState.COMMUNICATION_ERROR, new Integer(fnid), ioe); - } - - // Now handle the result - - // Now loop, reading the results - Object result = null; // our result - StringBuffer errorMessage = null; - int c; - boolean l_endQuery = false; - while (!l_endQuery) - { - c = stream.ReceiveChar(); - - switch (c) - { - case 'A': // Asynchronous Notify - //TODO: do something with this - int pid = stream.ReceiveInteger(4); - String msg = stream.ReceiveString(conn.getEncoding()); - break; - - //------------------------------ - // Error message returned - case 'E': - if ( errorMessage == null ) - errorMessage = new StringBuffer(); - errorMessage.append(stream.ReceiveString(conn.getEncoding())); - break; - - //------------------------------ - // Notice from backend - case 'N': - conn.addWarning(stream.ReceiveString(conn.getEncoding())); - break; - - case 'V': - int l_nextChar = stream.ReceiveChar(); - if (l_nextChar == 'G') - { - int sz = stream.ReceiveIntegerR(4); - // Return an Integer if - if (resulttype) - result = new Integer(stream.ReceiveIntegerR(sz)); - else - { - byte buf[] = new byte[sz]; - stream.Receive(buf, 0, sz); - result = buf; - } - //There should be a trailing '0' - int l_endChar = stream.ReceiveChar(); - } - else - { - //it must have been a '0', thus no results - } - break; - - case 'Z': - l_endQuery = true; - break; - - default: - throw new PSQLException("postgresql.fp.protocol", PSQLState.COMMUNICATION_ERROR, new Character((char)c)); - } - } - - if ( errorMessage != null ) - throw new PSQLException("postgresql.fp.error", PSQLState.COMMUNICATION_ERROR, errorMessage.toString()); - - return result; - } - } - - /* - * Send a function call to the PostgreSQL backend by name. - * - * Note: the mapping for the procedure name to function id needs to exist, - * usually to an earlier call to addfunction(). - * - * This is the prefered method to call, as function id's can/may change - * between versions of the backend. - * - * For an example of how this works, refer to org.postgresql.largeobject.LargeObject - * - * @param name Function name - * @param resulttype True if the result is an integer, false for other - * results - * @param args FastpathArguments to pass to fastpath - * @return null if no data, Integer if an integer result, or byte[] otherwise - * @exception SQLException if name is unknown or if a database-access error - * occurs. - * @see org.postgresql.largeobject.LargeObject - */ - public Object fastpath(String name, boolean resulttype, FastpathArg[] args) throws SQLException - { - if (Driver.logDebug) - Driver.debug("Fastpath: calling " + name); - return fastpath(getID(name), resulttype, args); - } - - /* - * This convenience method assumes that the return value is an Integer - * @param name Function name - * @param args Function arguments - * @return integer result - * @exception SQLException if a database-access error occurs or no result - */ - public int getInteger(String name, FastpathArg[] args) throws SQLException - { - Integer i = (Integer)fastpath(name, true, args); - if (i == null) - throw new PSQLException("postgresql.fp.expint", name); - return i.intValue(); - } - - /* - * This convenience method assumes that the return value is an Integer - * @param name Function name - * @param args Function arguments - * @return byte[] array containing result - * @exception SQLException if a database-access error occurs or no result - */ - public byte[] getData(String name, FastpathArg[] args) throws SQLException - { - return (byte[])fastpath(name, false, args); - } - - /* - * This adds a function to our lookup table. - * - * <p>User code should use the addFunctions method, which is based upon a - * query, rather than hard coding the oid. The oid for a function is not - * guaranteed to remain static, even on different servers of the same - * version. - * - * @param name Function name - * @param fnid Function id - */ - public void addFunction(String name, int fnid) - { - func.put(name, new Integer(fnid)); - } - - /* - * This takes a ResultSet containing two columns. Column 1 contains the - * function name, Column 2 the oid. - * - * <p>It reads the entire ResultSet, loading the values into the function - * table. - * - * <p><b>REMEMBER</b> to close() the resultset after calling this!! - * - * <p><b><em>Implementation note about function name lookups:</em></b> - * - * <p>PostgreSQL stores the function id's and their corresponding names in - * the pg_proc table. To speed things up locally, instead of querying each - * function from that table when required, a Hashtable is used. Also, only - * the function's required are entered into this table, keeping connection - * times as fast as possible. - * - * <p>The org.postgresql.largeobject.LargeObject class performs a query upon it's startup, - * and passes the returned ResultSet to the addFunctions() method here. - * - * <p>Once this has been done, the LargeObject api refers to the functions by - * name. - * - * <p>Dont think that manually converting them to the oid's will work. Ok, - * they will for now, but they can change during development (there was some - * discussion about this for V7.0), so this is implemented to prevent any - * unwarranted headaches in the future. - * - * @param rs ResultSet - * @exception SQLException if a database-access error occurs. - * @see org.postgresql.largeobject.LargeObjectManager - */ - public void addFunctions(ResultSet rs) throws SQLException - { - while (rs.next()) - { - func.put(rs.getString(1), new Integer(rs.getInt(2))); - } - } - - /* - * This returns the function id associated by its name - * - * <p>If addFunction() or addFunctions() have not been called for this name, - * then an SQLException is thrown. - * - * @param name Function name to lookup - * @return Function ID for fastpath call - * @exception SQLException is function is unknown. - */ - public int getID(String name) throws SQLException - { - Integer id = (Integer)func.get(name); - - // may be we could add a lookup to the database here, and store the result - // in our lookup table, throwing the exception if that fails. - // We must, however, ensure that if we do, any existing ResultSet is - // unaffected, otherwise we could break user code. - // - // so, until we know we can do this (needs testing, on the TODO list) - // for now, we throw the exception and do no lookups. - if (id == null) - throw new PSQLException("postgresql.fp.unknown", PSQLState.UNEXPECTED_ERROR, name); - - return id.intValue(); - } -} - diff --git a/src/interfaces/jdbc/org/postgresql/fastpath/FastpathArg.java b/src/interfaces/jdbc/org/postgresql/fastpath/FastpathArg.java deleted file mode 100644 index 248abca0f74..00000000000 --- a/src/interfaces/jdbc/org/postgresql/fastpath/FastpathArg.java +++ /dev/null @@ -1,116 +0,0 @@ -/*------------------------------------------------------------------------- - * - * FastpathArg.java - * Each fastpath call requires an array of arguments, the number and type - * dependent on the function being called. - * - * Copyright (c) 2003, PostgreSQL Global Development Group - * - * IDENTIFICATION - * $PostgreSQL: pgsql/src/interfaces/jdbc/org/postgresql/fastpath/FastpathArg.java,v 1.6 2003/11/29 19:52:09 pgsql Exp $ - * - *------------------------------------------------------------------------- - */ -package org.postgresql.fastpath; - -import java.io.IOException; - -public class FastpathArg -{ - /* - * Type of argument, true=integer, false=byte[] - */ - public boolean type; - - /* - * Integer value if type=true - */ - public int value; - - /* - * Byte value if type=false; - */ - public byte[] bytes; - - /* - * Constructs an argument that consists of an integer value - * @param value int value to set - */ - public FastpathArg(int value) - { - type = true; - this.value = value; - } - - /* - * Constructs an argument that consists of an array of bytes - * @param bytes array to store - */ - public FastpathArg(byte bytes[]) - { - type = false; - this.bytes = bytes; - } - - /* - * Constructs an argument that consists of part of a byte array - * @param buf source array - * @param off offset within array - * @param len length of data to include - */ - public FastpathArg(byte buf[], int off, int len) - { - type = false; - bytes = new byte[len]; - System.arraycopy(buf, off, bytes, 0, len); - } - - /* - * Constructs an argument that consists of a String. - * @param s String to store - */ - public FastpathArg(String s) - { - this(s.getBytes()); - } - - /* - * This sends this argument down the network stream. - * - * <p>The stream sent consists of the length.int4 then the contents. - * - * <p><b>Note:</b> This is called from Fastpath, and cannot be called from - * client code. - * - * @param s output stream - * @exception IOException if something failed on the network stream - */ - protected void send(org.postgresql.core.PGStream s) throws IOException - { - if (type) - { - // argument is an integer - s.SendInteger(4, 4); // size of an integer - s.SendInteger(value, 4); // integer value of argument - } - else - { - // argument is a byte array - s.SendInteger(bytes.length, 4); // size of array - s.Send(bytes); - } - } - - protected int sendSize() - { - if (type) - { - return 8; - } - else - { - return 4+bytes.length; - } - } -} - diff --git a/src/interfaces/jdbc/org/postgresql/geometric/PGbox.java b/src/interfaces/jdbc/org/postgresql/geometric/PGbox.java deleted file mode 100644 index 1913d373a90..00000000000 --- a/src/interfaces/jdbc/org/postgresql/geometric/PGbox.java +++ /dev/null @@ -1,119 +0,0 @@ -/*------------------------------------------------------------------------- - * - * PGbox.java - * This represents the box datatype within org.postgresql. - * - * Copyright (c) 2003, PostgreSQL Global Development Group - * - * IDENTIFICATION - * $PostgreSQL: pgsql/src/interfaces/jdbc/org/postgresql/geometric/PGbox.java,v 1.6 2003/11/29 19:52:09 pgsql Exp $ - * - *------------------------------------------------------------------------- - */ -package org.postgresql.geometric; - -import org.postgresql.util.PGobject; -import org.postgresql.util.PGtokenizer; -import org.postgresql.util.PSQLException; -import org.postgresql.util.PSQLState; - -import java.io.Serializable; -import java.sql.SQLException; - -public class PGbox extends PGobject implements Serializable, Cloneable -{ - /* - * These are the two points. - */ - public PGpoint point[] = new PGpoint[2]; - - /* - * @param x1 first x coordinate - * @param y1 first y coordinate - * @param x2 second x coordinate - * @param y2 second y coordinate - */ - public PGbox(double x1, double y1, double x2, double y2) - { - this(); - this.point[0] = new PGpoint(x1, y1); - this.point[1] = new PGpoint(x2, y2); - } - - /* - * @param p1 first point - * @param p2 second point - */ - public PGbox(PGpoint p1, PGpoint p2) - { - this(); - this.point[0] = p1; - this.point[1] = p2; - } - - /* - * @param s Box definition in PostgreSQL syntax - * @exception SQLException if definition is invalid - */ - public PGbox(String s) throws SQLException - { - this(); - setValue(s); - } - - /* - * Required constructor - */ - public PGbox() - { - setType("box"); - } - - /* - * This method sets the value of this object. It should be overidden, - * but still called by subclasses. - * - * @param value a string representation of the value of the object - * @exception SQLException thrown if value is invalid for this type - */ - public void setValue(String value) throws SQLException - { - PGtokenizer t = new PGtokenizer(value, ','); - if (t.getSize() != 2) - throw new PSQLException("postgresql.geo.box", PSQLState.DATA_TYPE_MISMATCH, value); - - point[0] = new PGpoint(t.getToken(0)); - point[1] = new PGpoint(t.getToken(1)); - } - - /* - * @param obj Object to compare with - * @return true if the two boxes are identical - */ - public boolean equals(Object obj) - { - if (obj instanceof PGbox) - { - PGbox p = (PGbox)obj; - return (p.point[0].equals(point[0]) && p.point[1].equals(point[1])) || - (p.point[0].equals(point[1]) && p.point[1].equals(point[0])); - } - return false; - } - - /* - * This must be overidden to allow the object to be cloned - */ - public Object clone() - { - return new PGbox((PGpoint)point[0].clone(), (PGpoint)point[1].clone()); - } - - /* - * @return the PGbox in the syntax expected by org.postgresql - */ - public String getValue() - { - return point[0].toString() + "," + point[1].toString(); - } -} diff --git a/src/interfaces/jdbc/org/postgresql/geometric/PGcircle.java b/src/interfaces/jdbc/org/postgresql/geometric/PGcircle.java deleted file mode 100644 index e559b3d90f0..00000000000 --- a/src/interfaces/jdbc/org/postgresql/geometric/PGcircle.java +++ /dev/null @@ -1,125 +0,0 @@ -/*------------------------------------------------------------------------- - * - * PGcircle.java - * This represents org.postgresql's circle datatype, consisting of a point - * and a radius - * - * Copyright (c) 2003, PostgreSQL Global Development Group - * - * IDENTIFICATION - * $PostgreSQL: pgsql/src/interfaces/jdbc/org/postgresql/geometric/PGcircle.java,v 1.7 2003/11/29 19:52:09 pgsql Exp $ - * - *------------------------------------------------------------------------- - */ -package org.postgresql.geometric; - -import org.postgresql.util.PGobject; -import org.postgresql.util.PGtokenizer; -import org.postgresql.util.PSQLException; -import org.postgresql.util.PSQLState; - -import java.io.Serializable; -import java.sql.SQLException; - -public class PGcircle extends PGobject implements Serializable, Cloneable -{ - /* - * This is the centre point - */ - public PGpoint center; - - /* - * This is the radius - */ - double radius; - - /* - * @param x coordinate of centre - * @param y coordinate of centre - * @param r radius of circle - */ - public PGcircle(double x, double y, double r) - { - this(new PGpoint(x, y), r); - } - - /* - * @param c PGpoint describing the circle's centre - * @param r radius of circle - */ - public PGcircle(PGpoint c, double r) - { - this(); - this.center = c; - this.radius = r; - } - - /* - * @param s definition of the circle in PostgreSQL's syntax. - * @exception SQLException on conversion failure - */ - public PGcircle(String s) throws SQLException - { - this(); - setValue(s); - } - - /* - * This constructor is used by the driver. - */ - public PGcircle() - { - setType("circle"); - } - - /* - * @param s definition of the circle in PostgreSQL's syntax. - * @exception SQLException on conversion failure - */ - public void setValue(String s) throws SQLException - { - PGtokenizer t = new PGtokenizer(PGtokenizer.removeAngle(s), ','); - if (t.getSize() != 2) - throw new PSQLException("postgresql.geo.circle", PSQLState.DATA_TYPE_MISMATCH, s); - - try - { - center = new PGpoint(t.getToken(0)); - radius = Double.valueOf(t.getToken(1)).doubleValue(); - } - catch (NumberFormatException e) - { - throw new PSQLException("postgresql.geo.circle", PSQLState.DATA_TYPE_MISMATCH, e); - } - } - - /* - * @param obj Object to compare with - * @return true if the two boxes are identical - */ - public boolean equals(Object obj) - { - if (obj instanceof PGcircle) - { - PGcircle p = (PGcircle)obj; - return p.center.equals(center) && p.radius == radius; - } - return false; - } - - /* - * This must be overidden to allow the object to be cloned - */ - public Object clone() - { - return new PGcircle((PGpoint)center.clone(), radius); - } - - /* - * @return the PGcircle in the syntax expected by org.postgresql - */ - public String getValue() - { - return "<" + center + "," + radius + ">"; - } -} diff --git a/src/interfaces/jdbc/org/postgresql/geometric/PGline.java b/src/interfaces/jdbc/org/postgresql/geometric/PGline.java deleted file mode 100644 index 7fd48de28ed..00000000000 --- a/src/interfaces/jdbc/org/postgresql/geometric/PGline.java +++ /dev/null @@ -1,118 +0,0 @@ -/*------------------------------------------------------------------------- - * - * PGline.java - * This implements a line consisting of two points. - * - * Copyright (c) 2003, PostgreSQL Global Development Group - * - * IDENTIFICATION - * $PostgreSQL: pgsql/src/interfaces/jdbc/org/postgresql/geometric/PGline.java,v 1.6 2003/11/29 19:52:09 pgsql Exp $ - * - *------------------------------------------------------------------------- - */ -package org.postgresql.geometric; - -import org.postgresql.util.PGobject; -import org.postgresql.util.PGtokenizer; -import org.postgresql.util.PSQLException; -import org.postgresql.util.PSQLState; - -import java.io.Serializable; -import java.sql.SQLException; - -/* - * Currently line is not yet implemented in the backend, but this class - * ensures that when it's done were ready for it. - */ -public class PGline extends PGobject implements Serializable, Cloneable -{ - /* - * These are the two points. - */ - public PGpoint point[] = new PGpoint[2]; - - /* - * @param x1 coordinate for first point - * @param y1 coordinate for first point - * @param x2 coordinate for second point - * @param y2 coordinate for second point - */ - public PGline(double x1, double y1, double x2, double y2) - { - this(new PGpoint(x1, y1), new PGpoint(x2, y2)); - } - - /* - * @param p1 first point - * @param p2 second point - */ - public PGline(PGpoint p1, PGpoint p2) - { - this(); - this.point[0] = p1; - this.point[1] = p2; - } - - /* - * @param s definition of the circle in PostgreSQL's syntax. - * @exception SQLException on conversion failure - */ - public PGline(String s) throws SQLException - { - this(); - setValue(s); - } - - /* - * reuired by the driver - */ - public PGline() - { - setType("line"); - } - - /* - * @param s Definition of the line segment in PostgreSQL's syntax - * @exception SQLException on conversion failure - */ - public void setValue(String s) throws SQLException - { - PGtokenizer t = new PGtokenizer(PGtokenizer.removeBox(s), ','); - if (t.getSize() != 2) - throw new PSQLException("postgresql.geo.line", PSQLState.DATA_TYPE_MISMATCH, s); - - point[0] = new PGpoint(t.getToken(0)); - point[1] = new PGpoint(t.getToken(1)); - } - - /* - * @param obj Object to compare with - * @return true if the two boxes are identical - */ - public boolean equals(Object obj) - { - if (obj instanceof PGline) - { - PGline p = (PGline)obj; - return (p.point[0].equals(point[0]) && p.point[1].equals(point[1])) || - (p.point[0].equals(point[1]) && p.point[1].equals(point[0])); - } - return false; - } - - /* - * This must be overidden to allow the object to be cloned - */ - public Object clone() - { - return new PGline((PGpoint)point[0].clone(), (PGpoint)point[1].clone()); - } - - /* - * @return the PGline in the syntax expected by org.postgresql - */ - public String getValue() - { - return "[" + point[0] + "," + point[1] + "]"; - } -} diff --git a/src/interfaces/jdbc/org/postgresql/geometric/PGlseg.java b/src/interfaces/jdbc/org/postgresql/geometric/PGlseg.java deleted file mode 100644 index 9663621cd40..00000000000 --- a/src/interfaces/jdbc/org/postgresql/geometric/PGlseg.java +++ /dev/null @@ -1,114 +0,0 @@ -/*------------------------------------------------------------------------- - * - * PGlseg.java - * This implements a lseg (line segment) consisting of two points - * - * Copyright (c) 2003, PostgreSQL Global Development Group - * - * IDENTIFICATION - * $PostgreSQL: pgsql/src/interfaces/jdbc/org/postgresql/geometric/PGlseg.java,v 1.6 2003/11/29 19:52:09 pgsql Exp $ - * - *------------------------------------------------------------------------- - */ -package org.postgresql.geometric; - -import org.postgresql.util.PGobject; -import org.postgresql.util.PGtokenizer; -import org.postgresql.util.PSQLException; -import org.postgresql.util.PSQLState; - -import java.io.Serializable; -import java.sql.SQLException; - -public class PGlseg extends PGobject implements Serializable, Cloneable -{ - /* - * These are the two points. - */ - public PGpoint point[] = new PGpoint[2]; - - /* - * @param x1 coordinate for first point - * @param y1 coordinate for first point - * @param x2 coordinate for second point - * @param y2 coordinate for second point - */ - public PGlseg(double x1, double y1, double x2, double y2) - { - this(new PGpoint(x1, y1), new PGpoint(x2, y2)); - } - - /* - * @param p1 first point - * @param p2 second point - */ - public PGlseg(PGpoint p1, PGpoint p2) - { - this(); - this.point[0] = p1; - this.point[1] = p2; - } - - /* - * @param s definition of the circle in PostgreSQL's syntax. - * @exception SQLException on conversion failure - */ - public PGlseg(String s) throws SQLException - { - this(); - setValue(s); - } - - /* - * reuired by the driver - */ - public PGlseg() - { - setType("lseg"); - } - - /* - * @param s Definition of the line segment in PostgreSQL's syntax - * @exception SQLException on conversion failure - */ - public void setValue(String s) throws SQLException - { - PGtokenizer t = new PGtokenizer(PGtokenizer.removeBox(s), ','); - if (t.getSize() != 2) - throw new PSQLException("postgresql.geo.lseg", PSQLState.DATA_TYPE_MISMATCH); - - point[0] = new PGpoint(t.getToken(0)); - point[1] = new PGpoint(t.getToken(1)); - } - - /* - * @param obj Object to compare with - * @return true if the two boxes are identical - */ - public boolean equals(Object obj) - { - if (obj instanceof PGlseg) - { - PGlseg p = (PGlseg)obj; - return (p.point[0].equals(point[0]) && p.point[1].equals(point[1])) || - (p.point[0].equals(point[1]) && p.point[1].equals(point[0])); - } - return false; - } - - /* - * This must be overidden to allow the object to be cloned - */ - public Object clone() - { - return new PGlseg((PGpoint)point[0].clone(), (PGpoint)point[1].clone()); - } - - /* - * @return the PGlseg in the syntax expected by org.postgresql - */ - public String getValue() - { - return "[" + point[0] + "," + point[1] + "]"; - } -} diff --git a/src/interfaces/jdbc/org/postgresql/geometric/PGpath.java b/src/interfaces/jdbc/org/postgresql/geometric/PGpath.java deleted file mode 100644 index 3c667e26c58..00000000000 --- a/src/interfaces/jdbc/org/postgresql/geometric/PGpath.java +++ /dev/null @@ -1,164 +0,0 @@ -/*------------------------------------------------------------------------- - * - * PGpath.java - * This implements a path (a multiple segmented line, which may be closed) - * - * Copyright (c) 2003, PostgreSQL Global Development Group - * - * IDENTIFICATION - * $PostgreSQL: pgsql/src/interfaces/jdbc/org/postgresql/geometric/PGpath.java,v 1.7 2003/11/29 19:52:09 pgsql Exp $ - * - *------------------------------------------------------------------------- - */ -package org.postgresql.geometric; - -import org.postgresql.util.PGobject; -import org.postgresql.util.PGtokenizer; -import org.postgresql.util.PSQLException; -import org.postgresql.util.PSQLState; - -import java.io.Serializable; -import java.sql.SQLException; - -public class PGpath extends PGobject implements Serializable, Cloneable -{ - /* - * True if the path is open, false if closed - */ - public boolean open; - - /* - * The points defining this path - */ - public PGpoint points[]; - - /* - * @param points the PGpoints that define the path - * @param open True if the path is open, false if closed - */ - public PGpath(PGpoint[] points, boolean open) - { - this(); - this.points = points; - this.open = open; - } - - /* - * Required by the driver - */ - public PGpath() - { - setType("path"); - } - - /* - * @param s definition of the circle in PostgreSQL's syntax. - * @exception SQLException on conversion failure - */ - public PGpath(String s) throws SQLException - { - this(); - setValue(s); - } - - /* - * @param s Definition of the path in PostgreSQL's syntax - * @exception SQLException on conversion failure - */ - public void setValue(String s) throws SQLException - { - // First test to see if were open - if (s.startsWith("[") && s.endsWith("]")) - { - open = true; - s = PGtokenizer.removeBox(s); - } - else if (s.startsWith("(") && s.endsWith(")")) - { - open = false; - s = PGtokenizer.removePara(s); - } - else - throw new PSQLException("postgresql.geo.path", PSQLState.DATA_TYPE_MISMATCH); - - PGtokenizer t = new PGtokenizer(s, ','); - int npoints = t.getSize(); - points = new PGpoint[npoints]; - for (int p = 0;p < npoints;p++) - points[p] = new PGpoint(t.getToken(p)); - } - - /* - * @param obj Object to compare with - * @return true if the two boxes are identical - */ - public boolean equals(Object obj) - { - if (obj instanceof PGpath) - { - PGpath p = (PGpath)obj; - - if (p.points.length != points.length) - return false; - - if (p.open != open) - return false; - - for (int i = 0;i < points.length;i++) - if (!points[i].equals(p.points[i])) - return false; - - return true; - } - return false; - } - - /* - * This must be overidden to allow the object to be cloned - */ - public Object clone() - { - PGpoint ary[] = new PGpoint[points.length]; - for (int i = 0;i < points.length;i++) - ary[i] = (PGpoint)points[i].clone(); - return new PGpath(ary, open); - } - - /* - * This returns the polygon in the syntax expected by org.postgresql - */ - public String getValue() - { - StringBuffer b = new StringBuffer(open ? "[" : "("); - - for (int p = 0;p < points.length;p++) - { - if (p > 0) - b.append(","); - b.append(points[p].toString()); - } - b.append(open ? "]" : ")"); - - return b.toString(); - } - - public boolean isOpen() - { - return open; - } - - public boolean isClosed() - { - return !open; - } - - public void closePath() - { - open = false; - } - - public void openPath() - { - open = true; - } -} diff --git a/src/interfaces/jdbc/org/postgresql/geometric/PGpoint.java b/src/interfaces/jdbc/org/postgresql/geometric/PGpoint.java deleted file mode 100644 index cff9cde0ebd..00000000000 --- a/src/interfaces/jdbc/org/postgresql/geometric/PGpoint.java +++ /dev/null @@ -1,184 +0,0 @@ -/*------------------------------------------------------------------------- - * - * PGline.java - * It maps to the point datatype in org.postgresql. - * - * Copyright (c) 2003, PostgreSQL Global Development Group - * - * IDENTIFICATION - * $PostgreSQL: pgsql/src/interfaces/jdbc/org/postgresql/geometric/PGpoint.java,v 1.7 2003/11/29 19:52:09 pgsql Exp $ - * - *------------------------------------------------------------------------- - */ -package org.postgresql.geometric; - -import org.postgresql.util.PGobject; -import org.postgresql.util.PGtokenizer; -import org.postgresql.util.PSQLException; -import org.postgresql.util.PSQLState; - -import java.awt.Point; -import java.io.Serializable; -import java.sql.SQLException; - -/* - * This implements a version of java.awt.Point, except it uses double - * to represent the coordinates. - */ -public class PGpoint extends PGobject implements Serializable, Cloneable -{ - /* - * The X coordinate of the point - */ - public double x; - - /* - * The Y coordinate of the point - */ - public double y; - - /* - * @param x coordinate - * @param y coordinate - */ - public PGpoint(double x, double y) - { - this(); - this.x = x; - this.y = y; - } - - /* - * This is called mainly from the other geometric types, when a - * point is imbeded within their definition. - * - * @param value Definition of this point in PostgreSQL's syntax - */ - public PGpoint(String value) throws SQLException - { - this(); - setValue(value); - } - - /* - * Required by the driver - */ - public PGpoint() - { - setType("point"); - } - - /* - * @param s Definition of this point in PostgreSQL's syntax - * @exception SQLException on conversion failure - */ - public void setValue(String s) throws SQLException - { - PGtokenizer t = new PGtokenizer(PGtokenizer.removePara(s), ','); - try - { - x = Double.valueOf(t.getToken(0)).doubleValue(); - y = Double.valueOf(t.getToken(1)).doubleValue(); - } - catch (NumberFormatException e) - { - throw new PSQLException("postgresql.geo.point", PSQLState.DATA_TYPE_MISMATCH, e.toString()); - } - } - - /* - * @param obj Object to compare with - * @return true if the two boxes are identical - */ - public boolean equals(Object obj) - { - if (obj instanceof PGpoint) - { - PGpoint p = (PGpoint)obj; - return x == p.x && y == p.y; - } - return false; - } - - /* - * This must be overidden to allow the object to be cloned - */ - public Object clone() - { - return new PGpoint(x, y); - } - - /* - * @return the PGpoint in the syntax expected by org.postgresql - */ - public String getValue() - { - return "(" + x + "," + y + ")"; - } - - /* - * Translate the point with the supplied amount. - * @param x integer amount to add on the x axis - * @param y integer amount to add on the y axis - */ - public void translate(int x, int y) - { - translate((double)x, (double)y); - } - - /* - * Translate the point with the supplied amount. - * @param x double amount to add on the x axis - * @param y double amount to add on the y axis - */ - public void translate(double x, double y) - { - this.x += x; - this.y += y; - } - - /* - * Moves the point to the supplied coordinates. - * @param x integer coordinate - * @param y integer coordinate - */ - public void move(int x, int y) - { - setLocation(x, y); - } - - /* - * Moves the point to the supplied coordinates. - * @param x double coordinate - * @param y double coordinate - */ - public void move(double x, double y) - { - this.x = x; - this.y = y; - } - - /* - * Moves the point to the supplied coordinates. - * refer to java.awt.Point for description of this - * @param x integer coordinate - * @param y integer coordinate - * @see java.awt.Point - */ - public void setLocation(int x, int y) - { - move((double)x, (double)y); - } - - /* - * Moves the point to the supplied java.awt.Point - * refer to java.awt.Point for description of this - * @param p Point to move to - * @see java.awt.Point - */ - public void setLocation(Point p) - { - setLocation(p.x, p.y); - } - -} diff --git a/src/interfaces/jdbc/org/postgresql/geometric/PGpolygon.java b/src/interfaces/jdbc/org/postgresql/geometric/PGpolygon.java deleted file mode 100644 index ec3b23e360b..00000000000 --- a/src/interfaces/jdbc/org/postgresql/geometric/PGpolygon.java +++ /dev/null @@ -1,118 +0,0 @@ -/*------------------------------------------------------------------------- - * - * PGline.java - * This implements the polygon datatype within PostgreSQL. - * - * Copyright (c) 2003, PostgreSQL Global Development Group - * - * IDENTIFICATION - * $PostgreSQL: pgsql/src/interfaces/jdbc/org/postgresql/geometric/PGpolygon.java,v 1.6 2003/11/29 19:52:09 pgsql Exp $ - * - *------------------------------------------------------------------------- - */ -package org.postgresql.geometric; - -import org.postgresql.util.PGobject; -import org.postgresql.util.PGtokenizer; -import java.io.Serializable; -import java.sql.SQLException; - -public class PGpolygon extends PGobject implements Serializable, Cloneable -{ - /* - * The points defining the polygon - */ - public PGpoint points[]; - - /* - * Creates a polygon using an array of PGpoints - * - * @param points the points defining the polygon - */ - public PGpolygon(PGpoint[] points) - { - this(); - this.points = points; - } - - /* - * @param s definition of the circle in PostgreSQL's syntax. - * @exception SQLException on conversion failure - */ - public PGpolygon(String s) throws SQLException - { - this(); - setValue(s); - } - - /* - * Required by the driver - */ - public PGpolygon() - { - setType("polygon"); - } - - /* - * @param s Definition of the polygon in PostgreSQL's syntax - * @exception SQLException on conversion failure - */ - public void setValue(String s) throws SQLException - { - PGtokenizer t = new PGtokenizer(PGtokenizer.removePara(s), ','); - int npoints = t.getSize(); - points = new PGpoint[npoints]; - for (int p = 0;p < npoints;p++) - points[p] = new PGpoint(t.getToken(p)); - } - - /* - * @param obj Object to compare with - * @return true if the two boxes are identical - */ - public boolean equals(Object obj) - { - if (obj instanceof PGpolygon) - { - PGpolygon p = (PGpolygon)obj; - - if (p.points.length != points.length) - return false; - - for (int i = 0;i < points.length;i++) - if (!points[i].equals(p.points[i])) - return false; - - return true; - } - return false; - } - - /* - * This must be overidden to allow the object to be cloned - */ - public Object clone() - { - PGpoint ary[] = new PGpoint[points.length]; - for (int i = 0;i < points.length;i++) - ary[i] = (PGpoint)points[i].clone(); - return new PGpolygon(ary); - } - - /* - * @return the PGpolygon in the syntax expected by org.postgresql - */ - public String getValue() - { - StringBuffer b = new StringBuffer(); - b.append("("); - for (int p = 0;p < points.length;p++) - { - if (p > 0) - b.append(","); - b.append(points[p].toString()); - } - b.append(")"); - return b.toString(); - } -} diff --git a/src/interfaces/jdbc/org/postgresql/jdbc1/AbstractJdbc1Connection.java b/src/interfaces/jdbc/org/postgresql/jdbc1/AbstractJdbc1Connection.java deleted file mode 100644 index ddf6eb48a12..00000000000 --- a/src/interfaces/jdbc/org/postgresql/jdbc1/AbstractJdbc1Connection.java +++ /dev/null @@ -1,1843 +0,0 @@ -/*------------------------------------------------------------------------- - * - * AbstractJdbc1Connection.java - * This class defines methods of the jdbc1 specification. This class is - * extended by org.postgresql.jdbc2.AbstractJdbc2Connection which adds - * the jdbc2 methods. The real Connection class (for jdbc1) is - * org.postgresql.jdbc1.Jdbc1Connection - * - * Copyright (c) 2003, PostgreSQL Global Development Group - * - * IDENTIFICATION - * $PostgreSQL: pgsql/src/interfaces/jdbc/org/postgresql/jdbc1/AbstractJdbc1Connection.java,v 1.29 2003/12/18 03:27:15 davec Exp $ - * - *------------------------------------------------------------------------- - */ -package org.postgresql.jdbc1; - - -import java.io.IOException; -import java.net.ConnectException; -import java.sql.*; -import java.util.*; -import org.postgresql.Driver; -import org.postgresql.PGNotification; -import org.postgresql.core.BaseConnection; -import org.postgresql.core.BaseResultSet; -import org.postgresql.core.BaseStatement; -import org.postgresql.core.Encoding; -import org.postgresql.core.PGStream; -import org.postgresql.core.QueryExecutor; -import org.postgresql.core.StartupPacket; -import org.postgresql.fastpath.Fastpath; -import org.postgresql.largeobject.LargeObjectManager; -import org.postgresql.util.MD5Digest; -import org.postgresql.util.PGobject; -import org.postgresql.util.PSQLException; -import org.postgresql.util.PSQLState; -import org.postgresql.util.UnixCrypt; - -public abstract class AbstractJdbc1Connection implements BaseConnection -{ - // This is the network stream associated with this connection - private PGStream pgStream; - - public PGStream getPGStream() { - return pgStream; - } - - protected String PG_HOST; - protected int PG_PORT; - protected String PG_USER; - protected String PG_DATABASE; - protected boolean PG_STATUS; - protected String compatible; - protected boolean useSSL; - - // The PID an cancellation key we get from the backend process - protected int pid; - protected int ckey; - - private Vector m_notifications; - - /* - The encoding to use for this connection. - */ - private Encoding encoding = Encoding.defaultEncoding(); - - private String dbVersionNumber; - - public boolean CONNECTION_OK = true; - public boolean CONNECTION_BAD = false; - - public boolean autoCommit = true; - public boolean readOnly = false; - - public Driver this_driver; - private String this_url; - private String cursor = null; // The positioned update cursor name - - private int PGProtocolVersionMajor = 2; - private int PGProtocolVersionMinor = 0; - public int getPGProtocolVersionMajor() { return PGProtocolVersionMajor; } - public int getPGProtocolVersionMinor() { return PGProtocolVersionMinor; } - - private static final int AUTH_REQ_OK = 0; - private static final int AUTH_REQ_KRB4 = 1; - private static final int AUTH_REQ_KRB5 = 2; - private static final int AUTH_REQ_PASSWORD = 3; - private static final int AUTH_REQ_CRYPT = 4; - private static final int AUTH_REQ_MD5 = 5; - private static final int AUTH_REQ_SCM = 6; - - - // These are used to cache oids, PGTypes and SQLTypes - private static Hashtable sqlTypeCache = new Hashtable(); // oid -> SQLType - private static Hashtable pgTypeCache = new Hashtable(); // oid -> PGType - private static Hashtable typeOidCache = new Hashtable(); //PGType -> oid - - // Now handle notices as warnings, so things like "show" now work - public SQLWarning firstWarning = null; - - /* - * Cache of the current isolation level - */ - private int isolationLevel = Connection.TRANSACTION_READ_COMMITTED; - - - public abstract Statement createStatement() throws SQLException; - public abstract DatabaseMetaData getMetaData() throws SQLException; - - /* - * This method actually opens the connection. It is called by Driver. - * - * @param host the hostname of the database back end - * @param port the port number of the postmaster process - * @param info a Properties[] thing of the user and password - * @param database the database to connect to - * @param url the URL of the connection - * @param d the Driver instantation of the connection - * @exception SQLException if a database access error occurs - */ - public void openConnection(String host, int port, Properties info, String database, String url, Driver d) throws SQLException - { - firstWarning = null; - - // Throw an exception if the user or password properties are missing - // This occasionally occurs when the client uses the properties version - // of getConnection(), and is a common question on the email lists - if (info.getProperty("user") == null) - throw new PSQLException("postgresql.con.user", PSQLState.CONNECTION_REJECTED); - - this_driver = (Driver)d; - this_url = url; - - PG_DATABASE = database; - PG_USER = info.getProperty("user"); - - String password = info.getProperty("password", ""); - PG_PORT = port; - - PG_HOST = host; - PG_STATUS = CONNECTION_BAD; - - if (info.getProperty("ssl") != null && Driver.sslEnabled()) - { - useSSL = true; - } - else - { - useSSL = false; - } - - if (info.getProperty("compatible") == null) - { - compatible = d.getMajorVersion() + "." + d.getMinorVersion(); - } - else - { - compatible = info.getProperty("compatible"); - } - - //Read loglevel arg and set the loglevel based on this value - //in addition to setting the log level enable output to - //standard out if no other printwriter is set - String l_logLevelProp = info.getProperty("loglevel", "0"); - int l_logLevel = 0; - try - { - l_logLevel = Integer.parseInt(l_logLevelProp); - if (l_logLevel > Driver.DEBUG || l_logLevel < Driver.INFO) - { - l_logLevel = 0; - } - } - catch (Exception l_e) - { - //invalid value for loglevel ignore - } - if (l_logLevel > 0) - { - Driver.setLogLevel(l_logLevel); - enableDriverManagerLogging(); - } - - //Print out the driver version number - if (Driver.logInfo) - Driver.info(Driver.getVersion()); - if (Driver.logDebug) { - Driver.debug(" ssl = " + useSSL); - Driver.debug(" compatible = " + compatible); - Driver.debug(" loglevel = " + l_logLevel); - } - - // Now make the initial connection - try - { - pgStream = new PGStream(host, port); - } - catch (ConnectException cex) - { - // Added by Peter Mount <[email protected]> - // ConnectException is thrown when the connection cannot be made. - // we trap this an return a more meaningful message for the end user - throw new PSQLException ("postgresql.con.refused", PSQLState.CONNECTION_REJECTED); - } - catch (IOException e) - { - throw new PSQLException ("postgresql.con.failed", PSQLState.CONNECTION_UNABLE_TO_CONNECT, e); - } - - //Now do the protocol work - if (haveMinimumCompatibleVersion("7.4")) { - openConnectionV3(host,port,info,database,url,d,password); - } else { - openConnectionV2(host,port,info,database,url,d,password); - } - } - - private void openConnectionV3(String p_host, int p_port, Properties p_info, String p_database, String p_url, Driver p_d, String p_password) throws SQLException - { - PGProtocolVersionMajor = 3; - if (Driver.logDebug) - Driver.debug("Using Protocol Version3"); - - // Now we need to construct and send an ssl startup packet - try - { - if (useSSL) { - if (Driver.logDebug) - Driver.debug("Asking server if it supports ssl"); - pgStream.SendInteger(8,4); - pgStream.SendInteger(80877103,4); - - // now flush the ssl packets to the backend - pgStream.flush(); - - // Now get the response from the backend, either an error message - // or an authentication request - int beresp = pgStream.ReceiveChar(); - if (Driver.logDebug) - Driver.debug("Server response was (S=Yes,N=No): "+(char)beresp); - switch (beresp) - { - case 'E': - // An error occured, so pass the error message to the - // user. - // - // The most common one to be thrown here is: - // "User authentication failed" - // - throw new PSQLException("postgresql.con.misc", PSQLState.CONNECTION_REJECTED, pgStream.ReceiveString(encoding)); - - case 'N': - // Server does not support ssl - throw new PSQLException("postgresql.con.sslnotsupported", PSQLState.CONNECTION_FAILURE); - - case 'S': - // Server supports ssl - if (Driver.logDebug) - Driver.debug("server does support ssl"); - Driver.makeSSL(pgStream); - break; - - default: - throw new PSQLException("postgresql.con.sslfail", PSQLState.CONNECTION_FAILURE); - } - } - } - catch (IOException e) - { - throw new PSQLException("postgresql.con.failed", PSQLState.CONNECTION_UNABLE_TO_CONNECT, e); - } - - - // Now we need to construct and send a startup packet - try - { - new StartupPacket(PGProtocolVersionMajor, - PGProtocolVersionMinor, - PG_USER, - p_database).writeTo(pgStream); - - // now flush the startup packets to the backend - pgStream.flush(); - - // Now get the response from the backend, either an error message - // or an authentication request - int areq = -1; // must have a value here - do - { - int beresp = pgStream.ReceiveChar(); - String salt = null; - byte [] md5Salt = new byte[4]; - switch (beresp) - { - case 'E': - // An error occured, so pass the error message to the - // user. - // - // The most common one to be thrown here is: - // "User authentication failed" - // - int l_elen = pgStream.ReceiveIntegerR(4); - if (l_elen > 30000) { - //if the error length is > than 30000 we assume this is really a v2 protocol - //server so try again with a v2 connection - //need to create a new connection and try again - try - { - pgStream = new PGStream(p_host, p_port); - } - catch (ConnectException cex) - { - // Added by Peter Mount <[email protected]> - // ConnectException is thrown when the connection cannot be made. - // we trap this an return a more meaningful message for the end user - throw new PSQLException ("postgresql.con.refused", PSQLState.CONNECTION_REJECTED); - } - catch (IOException e) - { - throw new PSQLException ("postgresql.con.failed", PSQLState.CONNECTION_UNABLE_TO_CONNECT, e); - } - openConnectionV2(p_host, p_port, p_info, p_database, p_url, p_d, p_password); - return; - } - throw new PSQLException("postgresql.con.misc", PSQLState.CONNECTION_REJECTED, PSQLException.parseServerError(encoding.decode(pgStream.Receive(l_elen-4)))); - - case 'R': - // Get the message length - int l_msgLen = pgStream.ReceiveIntegerR(4); - // Get the type of request - areq = pgStream.ReceiveIntegerR(4); - // Get the crypt password salt if there is one - if (areq == AUTH_REQ_CRYPT) - { - byte[] rst = new byte[2]; - rst[0] = (byte)pgStream.ReceiveChar(); - rst[1] = (byte)pgStream.ReceiveChar(); - salt = new String(rst, 0, 2); - if (Driver.logDebug) - Driver.debug("Crypt salt=" + salt); - } - - // Or get the md5 password salt if there is one - if (areq == AUTH_REQ_MD5) - { - - md5Salt[0] = (byte)pgStream.ReceiveChar(); - md5Salt[1] = (byte)pgStream.ReceiveChar(); - md5Salt[2] = (byte)pgStream.ReceiveChar(); - md5Salt[3] = (byte)pgStream.ReceiveChar(); - salt = new String(md5Salt, 0, 4); - if (Driver.logDebug) - Driver.debug("MD5 salt=" + salt); - } - - // now send the auth packet - switch (areq) - { - case AUTH_REQ_OK: - break; - - case AUTH_REQ_KRB4: - if (Driver.logDebug) - Driver.debug("postgresql: KRB4"); - throw new PSQLException("postgresql.con.kerb4", PSQLState.CONNECTION_REJECTED); - - case AUTH_REQ_KRB5: - if (Driver.logDebug) - Driver.debug("postgresql: KRB5"); - throw new PSQLException("postgresql.con.kerb5", PSQLState.CONNECTION_REJECTED); - - case AUTH_REQ_SCM: - if (Driver.logDebug) - Driver.debug("postgresql: SCM"); - throw new PSQLException("postgresql.con.scm", PSQLState.CONNECTION_REJECTED); - - - case AUTH_REQ_PASSWORD: - if (Driver.logDebug) - Driver.debug("postgresql: PASSWORD"); - pgStream.SendChar('p'); - pgStream.SendInteger(5 + p_password.length(), 4); - pgStream.Send(p_password.getBytes()); - pgStream.SendChar(0); - pgStream.flush(); - break; - - case AUTH_REQ_CRYPT: - if (Driver.logDebug) - Driver.debug("postgresql: CRYPT"); - String crypted = UnixCrypt.crypt(salt, p_password); - pgStream.SendChar('p'); - pgStream.SendInteger(5 + crypted.length(), 4); - pgStream.Send(crypted.getBytes()); - pgStream.SendChar(0); - pgStream.flush(); - break; - - case AUTH_REQ_MD5: - if (Driver.logDebug) - Driver.debug("postgresql: MD5"); - byte[] digest = MD5Digest.encode(PG_USER, p_password, md5Salt); - pgStream.SendChar('p'); - pgStream.SendInteger(5 + digest.length, 4); - pgStream.Send(digest); - pgStream.SendChar(0); - pgStream.flush(); - break; - - default: - throw new PSQLException("postgresql.con.auth", PSQLState.CONNECTION_REJECTED, new Integer(areq)); - } - break; - - default: - throw new PSQLException("postgresql.con.authfail", PSQLState.CONNECTION_REJECTED); - } - } - while (areq != AUTH_REQ_OK); - - } - catch (IOException e) - { - throw new PSQLException("postgresql.con.failed", PSQLState.CONNECTION_UNABLE_TO_CONNECT, e); - } - - int beresp; - do - { - beresp = pgStream.ReceiveChar(); - switch (beresp) - { - case 'Z': - //ready for query - break; - case 'K': - int l_msgLen = pgStream.ReceiveIntegerR(4); - if (l_msgLen != 12) throw new PSQLException("postgresql.con.setup", PSQLState.CONNECTION_UNABLE_TO_CONNECT); - pid = pgStream.ReceiveIntegerR(4); - ckey = pgStream.ReceiveIntegerR(4); - break; - case 'E': - int l_elen = pgStream.ReceiveIntegerR(4); - throw new PSQLException("postgresql.con.backend", PSQLState.CONNECTION_UNABLE_TO_CONNECT, PSQLException.parseServerError(encoding.decode(pgStream.Receive(l_elen-4)))); - case 'N': - int l_nlen = pgStream.ReceiveIntegerR(4); - addWarning(encoding.decode(pgStream.Receive(l_nlen-4))); - break; - case 'S': - //TODO: handle parameter status messages - int l_len = pgStream.ReceiveIntegerR(4); - String l_pStatus = encoding.decode(pgStream.Receive(l_len-4)); - if (Driver.logDebug) - Driver.debug("ParameterStatus="+ l_pStatus); - break; - default: - if (Driver.logDebug) - Driver.debug("invalid state="+ (char)beresp); - throw new PSQLException("postgresql.con.setup", PSQLState.CONNECTION_UNABLE_TO_CONNECT); - } - } - while (beresp != 'Z'); - // read ReadyForQuery - if (pgStream.ReceiveIntegerR(4) != 5) throw new PSQLException("postgresql.con.setup", PSQLState.CONNECTION_UNABLE_TO_CONNECT); - //TODO: handle transaction status - char l_tStatus = (char)pgStream.ReceiveChar(); - - // "pg_encoding_to_char(1)" will return 'EUC_JP' for a backend compiled with multibyte, - // otherwise it's hardcoded to 'SQL_ASCII'. - // If the backend doesn't know about multibyte we can't assume anything about the encoding - // used, so we denote this with 'UNKNOWN'. - //Note: begining with 7.2 we should be using pg_client_encoding() which - //is new in 7.2. However it isn't easy to conditionally call this new - //function, since we don't yet have the information as to what server - //version we are talking to. Thus we will continue to call - //getdatabaseencoding() until we drop support for 7.1 and older versions - //or until someone comes up with a conditional way to run one or - //the other function depending on server version that doesn't require - //two round trips to the server per connection - - final String encodingQuery = - "case when pg_encoding_to_char(1) = 'SQL_ASCII' then 'UNKNOWN' else getdatabaseencoding() end"; - - // Set datestyle and fetch db encoding in a single call, to avoid making - // more than one round trip to the backend during connection startup. - - - BaseResultSet resultSet - = execSQL("set datestyle to 'ISO'; select version(), " + encodingQuery + ";"); - - if (! resultSet.next()) - { - throw new PSQLException("postgresql.con.failed.bad.encoding", PSQLState.CONNECTION_UNABLE_TO_CONNECT); - } - String version = resultSet.getString(1); - dbVersionNumber = extractVersionNumber(version); - - String dbEncoding = resultSet.getString(2); - encoding = Encoding.getEncoding(dbEncoding, p_info.getProperty("charSet")); - //In 7.3 we are forced to do a second roundtrip to handle the case - //where a database may not be running in autocommit mode - //jdbc by default assumes autocommit is on until setAutoCommit(false) - //is called. Therefore we need to ensure a new connection is - //initialized to autocommit on. - //We also set the client encoding so that the driver only needs - //to deal with utf8. We can only do this in 7.3 because multibyte - //support is now always included - if (haveMinimumServerVersion("7.3")) - { - BaseResultSet acRset = - //TODO: if protocol V3 we can set the client encoding in startup - execSQL("set client_encoding = 'UNICODE'"); - //set encoding to be unicode - encoding = Encoding.getEncoding("UNICODE", null); - - } - - // Initialise object handling - initObjectTypes(); - - // Mark the connection as ok, and cleanup - PG_STATUS = CONNECTION_OK; - } - - private void openConnectionV2(String host, int port, Properties info, String database, String url, Driver d, String password) throws SQLException - { - PGProtocolVersionMajor = 2; - if (Driver.logDebug) - Driver.debug("Using Protocol Version2"); - - // Now we need to construct and send an ssl startup packet - try - { - if (useSSL) { - if (Driver.logDebug) - Driver.debug("Asking server if it supports ssl"); - pgStream.SendInteger(8,4); - pgStream.SendInteger(80877103,4); - - // now flush the ssl packets to the backend - pgStream.flush(); - - // Now get the response from the backend, either an error message - // or an authentication request - int beresp = pgStream.ReceiveChar(); - if (Driver.logDebug) - Driver.debug("Server response was (S=Yes,N=No): "+(char)beresp); - switch (beresp) - { - case 'E': - // An error occured, so pass the error message to the - // user. - // - // The most common one to be thrown here is: - // "User authentication failed" - // - throw new PSQLException("postgresql.con.misc", PSQLState.CONNECTION_REJECTED, pgStream.ReceiveString(encoding)); - - case 'N': - // Server does not support ssl - throw new PSQLException("postgresql.con.sslnotsupported", PSQLState.CONNECTION_FAILURE); - - case 'S': - // Server supports ssl - if (Driver.logDebug) - Driver.debug("server does support ssl"); - Driver.makeSSL(pgStream); - break; - - default: - throw new PSQLException("postgresql.con.sslfail", PSQLState.CONNECTION_FAILURE); - } - } - } - catch (IOException e) - { - throw new PSQLException("postgresql.con.failed", PSQLState.CONNECTION_UNABLE_TO_CONNECT, e); - } - - - // Now we need to construct and send a startup packet - try - { - new StartupPacket(PGProtocolVersionMajor, - PGProtocolVersionMinor, - PG_USER, - database).writeTo(pgStream); - - // now flush the startup packets to the backend - pgStream.flush(); - - // Now get the response from the backend, either an error message - // or an authentication request - int areq = -1; // must have a value here - do - { - int beresp = pgStream.ReceiveChar(); - String salt = null; - byte [] md5Salt = new byte[4]; - switch (beresp) - { - case 'E': - // An error occured, so pass the error message to the - // user. - // - // The most common one to be thrown here is: - // "User authentication failed" - // - throw new PSQLException("postgresql.con.misc", PSQLState.CONNECTION_REJECTED, pgStream.ReceiveString(encoding)); - - case 'R': - // Get the type of request - areq = pgStream.ReceiveIntegerR(4); - // Get the crypt password salt if there is one - if (areq == AUTH_REQ_CRYPT) - { - byte[] rst = new byte[2]; - rst[0] = (byte)pgStream.ReceiveChar(); - rst[1] = (byte)pgStream.ReceiveChar(); - salt = new String(rst, 0, 2); - if (Driver.logDebug) - Driver.debug("Crypt salt=" + salt); - } - - // Or get the md5 password salt if there is one - if (areq == AUTH_REQ_MD5) - { - - md5Salt[0] = (byte)pgStream.ReceiveChar(); - md5Salt[1] = (byte)pgStream.ReceiveChar(); - md5Salt[2] = (byte)pgStream.ReceiveChar(); - md5Salt[3] = (byte)pgStream.ReceiveChar(); - salt = new String(md5Salt, 0, 4); - if (Driver.logDebug) - Driver.debug("MD5 salt=" + salt); - } - - // now send the auth packet - switch (areq) - { - case AUTH_REQ_OK: - break; - - case AUTH_REQ_KRB4: - if (Driver.logDebug) - Driver.debug("postgresql: KRB4"); - throw new PSQLException("postgresql.con.kerb4", PSQLState.CONNECTION_REJECTED); - - case AUTH_REQ_KRB5: - if (Driver.logDebug) - Driver.debug("postgresql: KRB5"); - throw new PSQLException("postgresql.con.kerb5", PSQLState.CONNECTION_REJECTED); - - case AUTH_REQ_PASSWORD: - if (Driver.logDebug) - Driver.debug("postgresql: PASSWORD"); - pgStream.SendInteger(5 + password.length(), 4); - pgStream.Send(password.getBytes()); - pgStream.SendInteger(0, 1); - pgStream.flush(); - break; - - case AUTH_REQ_CRYPT: - if (Driver.logDebug) - Driver.debug("postgresql: CRYPT"); - String crypted = UnixCrypt.crypt(salt, password); - pgStream.SendInteger(5 + crypted.length(), 4); - pgStream.Send(crypted.getBytes()); - pgStream.SendInteger(0, 1); - pgStream.flush(); - break; - - case AUTH_REQ_MD5: - if (Driver.logDebug) - Driver.debug("postgresql: MD5"); - byte[] digest = MD5Digest.encode(PG_USER, password, md5Salt); - pgStream.SendInteger(5 + digest.length, 4); - pgStream.Send(digest); - pgStream.SendInteger(0, 1); - pgStream.flush(); - break; - - default: - throw new PSQLException("postgresql.con.auth", PSQLState.CONNECTION_REJECTED, new Integer(areq)); - } - break; - - default: - throw new PSQLException("postgresql.con.authfail", PSQLState.CONNECTION_REJECTED); - } - } - while (areq != AUTH_REQ_OK); - - } - catch (IOException e) - { - //Should be passing exception as arg. - throw new PSQLException("postgresql.con.failed", PSQLState.CONNECTION_UNABLE_TO_CONNECT, e); - } - - - // As of protocol version 2.0, we should now receive the cancellation key and the pid - int beresp; - do - { - beresp = pgStream.ReceiveChar(); - switch (beresp) - { - case 'K': - pid = pgStream.ReceiveIntegerR(4); - ckey = pgStream.ReceiveIntegerR(4); - break; - case 'E': - throw new PSQLException("postgresql.con.backend", PSQLState.CONNECTION_UNABLE_TO_CONNECT, pgStream.ReceiveString(encoding)); - case 'N': - addWarning(pgStream.ReceiveString(encoding)); - break; - default: - throw new PSQLException("postgresql.con.setup", PSQLState.CONNECTION_UNABLE_TO_CONNECT); - } - } - while (beresp == 'N'); - - // Expect ReadyForQuery packet - do - { - beresp = pgStream.ReceiveChar(); - switch (beresp) - { - case 'Z': - break; - case 'N': - addWarning(pgStream.ReceiveString(encoding)); - break; - case 'E': - throw new PSQLException("postgresql.con.backend", PSQLState.CONNECTION_UNABLE_TO_CONNECT, pgStream.ReceiveString(encoding)); - default: - throw new PSQLException("postgresql.con.setup", PSQLState.CONNECTION_UNABLE_TO_CONNECT); - } - } - while (beresp == 'N'); - // "pg_encoding_to_char(1)" will return 'EUC_JP' for a backend compiled with multibyte, - // otherwise it's hardcoded to 'SQL_ASCII'. - // If the backend doesn't know about multibyte we can't assume anything about the encoding - // used, so we denote this with 'UNKNOWN'. - //Note: begining with 7.2 we should be using pg_client_encoding() which - //is new in 7.2. However it isn't easy to conditionally call this new - //function, since we don't yet have the information as to what server - //version we are talking to. Thus we will continue to call - //getdatabaseencoding() until we drop support for 7.1 and older versions - //or until someone comes up with a conditional way to run one or - //the other function depending on server version that doesn't require - //two round trips to the server per connection - - final String encodingQuery = - "case when pg_encoding_to_char(1) = 'SQL_ASCII' then 'UNKNOWN' else getdatabaseencoding() end"; - - // Set datestyle and fetch db encoding in a single call, to avoid making - // more than one round trip to the backend during connection startup. - - - BaseResultSet resultSet - = execSQL("set datestyle to 'ISO'; select version(), " + encodingQuery + ";"); - - if (! resultSet.next()) - { - throw new PSQLException("postgresql.con.failed.bad.encoding", PSQLState.CONNECTION_UNABLE_TO_CONNECT); - } - String version = resultSet.getString(1); - dbVersionNumber = extractVersionNumber(version); - - String dbEncoding = resultSet.getString(2); - encoding = Encoding.getEncoding(dbEncoding, info.getProperty("charSet")); - - //TODO: remove this once the set is done as part of V3protocol connection initiation - if (haveMinimumServerVersion("7.4")) - { - BaseResultSet acRset = - execSQL("set client_encoding = 'UNICODE'"); - - //set encoding to be unicode - encoding = Encoding.getEncoding("UNICODE", null); - } - - //In 7.3 we are forced to do a second roundtrip to handle the case - //where a database may not be running in autocommit mode - //jdbc by default assumes autocommit is on until setAutoCommit(false) - //is called. Therefore we need to ensure a new connection is - //initialized to autocommit on. - //We also set the client encoding so that the driver only needs - //to deal with utf8. We can only do this in 7.3+ because multibyte - //support is now always included - if (haveMinimumServerVersion("7.3") && !haveMinimumServerVersion("7.4")) - { - BaseResultSet acRset = - execSQL("set client_encoding = 'UNICODE'; show autocommit"); - - //set encoding to be unicode - encoding = Encoding.getEncoding("UNICODE", null); - - if (!acRset.next()) - { - throw new PSQLException("postgresql.con.failed.bad.autocommit", PSQLState.CONNECTION_UNABLE_TO_CONNECT); - } - //if autocommit is currently off we need to turn it on - //note that we will be in a transaction because the select above - //will have initiated the transaction so we need a commit - //to make the setting permanent - if (acRset.getString(1).equals("off")) - { - execSQL("set autocommit = on; commit;"); - } - } - - // Initialise object handling - initObjectTypes(); - - // Mark the connection as ok, and cleanup - PG_STATUS = CONNECTION_OK; - } - - /* - * Return the instance of org.postgresql.Driver - * that created this connection - */ - public Driver getDriver() - { - return this_driver; - } - - - /* - * This adds a warning to the warning chain. - * @param msg message to add - */ - public void addWarning(String msg) - { - // Add the warning to the chain - if (firstWarning != null) - firstWarning.setNextWarning(new SQLWarning(msg)); - else - firstWarning = new SQLWarning(msg); - - // Now check for some specific messages - - // This is obsolete in 6.5, but I've left it in here so if we need to use this - // technique again, we'll know where to place it. - // - // This is generated by the SQL "show datestyle" - //if (msg.startsWith("NOTICE:") && msg.indexOf("DateStyle")>0) { - //// 13 is the length off "DateStyle is " - //msg = msg.substring(msg.indexOf("DateStyle is ")+13); - // - //for(int i=0;i<dateStyles.length;i+=2) - //if (msg.startsWith(dateStyles[i])) - //currentDateStyle=i+1; // this is the index of the format - //} - } - - /** Simple query execution. - */ - public BaseResultSet execSQL (String s) throws SQLException - { - final Object[] nullarr = new Object[0]; - BaseStatement stat = (BaseStatement) createStatement(); - return QueryExecutor.execute(new String[] { s }, - nullarr, - stat); - } - - /* - * In SQL, a result table can be retrieved through a cursor that - * is named. The current row of a result can be updated or deleted - * using a positioned update/delete statement that references the - * cursor name. - * - * We support one cursor per connection. - * - * setCursorName sets the cursor name. - * - * @param cursor the cursor name - * @exception SQLException if a database access error occurs - */ - public void setCursorName(String cursor) throws SQLException - { - this.cursor = cursor; - } - - /* - * getCursorName gets the cursor name. - * - * @return the current cursor name - * @exception SQLException if a database access error occurs - */ - public String getCursorName() throws SQLException - { - return cursor; - } - - /* - * We are required to bring back certain information by - * the DatabaseMetaData class. These functions do that. - * - * Method getURL() brings back the URL (good job we saved it) - * - * @return the url - * @exception SQLException just in case... - */ - public String getURL() throws SQLException - { - return this_url; - } - - /* - * Method getUserName() brings back the User Name (again, we - * saved it) - * - * @return the user name - * @exception SQLException just in case... - */ - int lastMessage = 0; - public String getUserName() throws SQLException - { - return PG_USER; - } - - /* - * Get the character encoding to use for this connection. - */ - public Encoding getEncoding() throws SQLException - { - return encoding; - } - - /* - * This returns the Fastpath API for the current connection. - * - * <p><b>NOTE:</b> This is not part of JDBC, but allows access to - * functions on the org.postgresql backend itself. - * - * <p>It is primarily used by the LargeObject API - * - * <p>The best way to use this is as follows: - * - * <p><pre> - * import org.postgresql.fastpath.*; - * ... - * Fastpath fp = ((org.postgresql.Connection)myconn).getFastpathAPI(); - * </pre> - * - * <p>where myconn is an open Connection to org.postgresql. - * - * @return Fastpath object allowing access to functions on the org.postgresql - * backend. - * @exception SQLException by Fastpath when initialising for first time - */ - public Fastpath getFastpathAPI() throws SQLException - { - if (fastpath == null) - fastpath = new Fastpath(this, pgStream); - return fastpath; - } - - // This holds a reference to the Fastpath API if already open - private Fastpath fastpath = null; - - /* - * This returns the LargeObject API for the current connection. - * - * <p><b>NOTE:</b> This is not part of JDBC, but allows access to - * functions on the org.postgresql backend itself. - * - * <p>The best way to use this is as follows: - * - * <p><pre> - * import org.postgresql.largeobject.*; - * ... - * LargeObjectManager lo = ((org.postgresql.Connection)myconn).getLargeObjectAPI(); - * </pre> - * - * <p>where myconn is an open Connection to org.postgresql. - * - * @return LargeObject object that implements the API - * @exception SQLException by LargeObject when initialising for first time - */ - public LargeObjectManager getLargeObjectAPI() throws SQLException - { - if (largeobject == null) - largeobject = new LargeObjectManager(this); - return largeobject; - } - - // This holds a reference to the LargeObject API if already open - private LargeObjectManager largeobject = null; - - /* - * This method is used internally to return an object based around - * org.postgresql's more unique data types. - * - * <p>It uses an internal Hashtable to get the handling class. If the - * type is not supported, then an instance of org.postgresql.util.PGobject - * is returned. - * - * You can use the getValue() or setValue() methods to handle the returned - * object. Custom objects can have their own methods. - * - * @return PGobject for this type, and set to value - * @exception SQLException if value is not correct for this type - */ - public Object getObject(String type, String value) throws SQLException - { - try - { - Object o = objectTypes.get(type); - - // If o is null, then the type is unknown. - // If o is not null, and it is a String, then its a class name that - // extends PGobject. - // - // This is used to implement the org.postgresql unique types (like lseg, - // point, etc). - if (o != null && o instanceof String) - { - // 6.3 style extending PG_Object - PGobject obj = null; - obj = (PGobject)(Class.forName((String)o).newInstance()); - obj.setType(type); - obj.setValue(value); - return (Object)obj; - } - } - catch (SQLException sx) - { - // rethrow the exception. Done because we capture any others next - sx.fillInStackTrace(); - throw sx; - } - catch (Exception ex) - { - throw new PSQLException("postgresql.con.creobj", PSQLState.CONNECTION_FAILURE, type, ex); - } - - // should never be reached - return null; - } - - /* - * This allows client code to add a handler for one of org.postgresql's - * more unique data types. - * - * <p><b>NOTE:</b> This is not part of JDBC, but an extension. - * - * <p>The best way to use this is as follows: - * - * <p><pre> - * ... - * ((org.postgresql.Connection)myconn).addDataType("mytype","my.class.name"); - * ... - * </pre> - * - * <p>where myconn is an open Connection to org.postgresql. - * - * <p>The handling class must extend org.postgresql.util.PGobject - * - * @see org.postgresql.util.PGobject - */ - public void addDataType(String type, String name) - { - objectTypes.put(type, name); - } - - // This holds the available types - private Hashtable objectTypes = new Hashtable(); - - // This array contains the types that are supported as standard. - // - // The first entry is the types name on the database, the second - // the full class name of the handling class. - // - private static final String defaultObjectTypes[][] = { - {"box", "org.postgresql.geometric.PGbox"}, - {"circle", "org.postgresql.geometric.PGcircle"}, - {"line", "org.postgresql.geometric.PGline"}, - {"lseg", "org.postgresql.geometric.PGlseg"}, - {"path", "org.postgresql.geometric.PGpath"}, - {"point", "org.postgresql.geometric.PGpoint"}, - {"polygon", "org.postgresql.geometric.PGpolygon"}, - {"money", "org.postgresql.util.PGmoney"} - }; - - // This initialises the objectTypes hashtable - private void initObjectTypes() - { - for (int i = 0;i < defaultObjectTypes.length;i++) - objectTypes.put(defaultObjectTypes[i][0], defaultObjectTypes[i][1]); - } - - /* - * In some cases, it is desirable to immediately release a Connection's - * database and JDBC resources instead of waiting for them to be - * automatically released (cant think why off the top of my head) - * - * <B>Note:</B> A Connection is automatically closed when it is - * garbage collected. Certain fatal errors also result in a closed - * connection. - * - * @exception SQLException if a database access error occurs - */ - public void close() throws SQLException - { - if (getPGProtocolVersionMajor() == 3) { - closeV3(); - } else { - closeV2(); - } - } - - public void closeV3() throws SQLException - { - if (pgStream != null) - { - try - { - pgStream.SendChar('X'); - pgStream.SendInteger(4,4); - pgStream.flush(); - pgStream.close(); - } - catch (IOException e) - {} - finally - { - pgStream = null; - } - } - } - - public void closeV2() throws SQLException - { - if (pgStream != null) - { - try - { - pgStream.SendChar('X'); - pgStream.flush(); - pgStream.close(); - } - catch (IOException e) - {} - finally - { - pgStream = null; - } - } - } - - /* - * A driver may convert the JDBC sql grammar into its system's - * native SQL grammar prior to sending it; nativeSQL returns the - * native form of the statement that the driver would have sent. - * - * @param sql a SQL statement that may contain one or more '?' - * parameter placeholders - * @return the native form of this statement - * @exception SQLException if a database access error occurs - */ - public String nativeSQL(String sql) throws SQLException - { - return sql; - } - - /* - * The first warning reported by calls on this Connection is - * returned. - * - * <B>Note:</B> Sebsequent warnings will be changed to this - * SQLWarning - * - * @return the first SQLWarning or null - * @exception SQLException if a database access error occurs - */ - public SQLWarning getWarnings() throws SQLException - { - return firstWarning; - } - - /* - * After this call, getWarnings returns null until a new warning - * is reported for this connection. - * - * @exception SQLException if a database access error occurs - */ - public void clearWarnings() throws SQLException - { - firstWarning = null; - } - - - /* - * You can put a connection in read-only mode as a hunt to enable - * database optimizations - * - * <B>Note:</B> setReadOnly cannot be called while in the middle - * of a transaction - * - * @param readOnly - true enables read-only mode; false disables it - * @exception SQLException if a database access error occurs - */ - public void setReadOnly(boolean readOnly) throws SQLException - { - this.readOnly = readOnly; - } - - /* - * Tests to see if the connection is in Read Only Mode. Note that - * we cannot really put the database in read only mode, but we pretend - * we can by returning the value of the readOnly flag - * - * @return true if the connection is read only - * @exception SQLException if a database access error occurs - */ - public boolean isReadOnly() throws SQLException - { - return readOnly; - } - - /* - * If a connection is in auto-commit mode, than all its SQL - * statements will be executed and committed as individual - * transactions. Otherwise, its SQL statements are grouped - * into transactions that are terminated by either commit() - * or rollback(). By default, new connections are in auto- - * commit mode. The commit occurs when the statement completes - * or the next execute occurs, whichever comes first. In the - * case of statements returning a ResultSet, the statement - * completes when the last row of the ResultSet has been retrieved - * or the ResultSet has been closed. In advanced cases, a single - * statement may return multiple results as well as output parameter - * values. Here the commit occurs when all results and output param - * values have been retrieved. - * - * @param autoCommit - true enables auto-commit; false disables it - * @exception SQLException if a database access error occurs - */ - public void setAutoCommit(boolean autoCommit) throws SQLException - { - if (this.autoCommit == autoCommit) - return ; - if (autoCommit) - { - execSQL("end"); - } - else - { - if (haveMinimumServerVersion("7.1")) - { - execSQL("begin;" + getIsolationLevelSQL()); - } - else - { - execSQL("begin"); - execSQL(getIsolationLevelSQL()); - } - } - this.autoCommit = autoCommit; - } - - /* - * gets the current auto-commit state - * - * @return Current state of the auto-commit mode - * @see setAutoCommit - */ - public boolean getAutoCommit() - { - return this.autoCommit; - } - - /* - * The method commit() makes all changes made since the previous - * commit/rollback permanent and releases any database locks currently - * held by the Connection. This method should only be used when - * auto-commit has been disabled. (If autoCommit == true, then we - * just return anyhow) - * - * @exception SQLException if a database access error occurs - * @see setAutoCommit - */ - public void commit() throws SQLException - { - if (autoCommit) - return ; - //TODO: delay starting new transaction until first command - if (haveMinimumServerVersion("7.1")) - { - execSQL("commit;begin;" + getIsolationLevelSQL()); - } - else - { - execSQL("commit"); - execSQL("begin"); - execSQL(getIsolationLevelSQL()); - } - } - - /* - * The method rollback() drops all changes made since the previous - * commit/rollback and releases any database locks currently held by - * the Connection. - * - * @exception SQLException if a database access error occurs - * @see commit - */ - public void rollback() throws SQLException - { - if (autoCommit) - return ; - //TODO: delay starting transaction until first command - if (haveMinimumServerVersion("7.1")) - { - execSQL("rollback; begin;" + getIsolationLevelSQL()); - } - else - { - execSQL("rollback"); - execSQL("begin"); - execSQL(getIsolationLevelSQL()); - } - } - - /* - * Get this Connection's current transaction isolation mode. - * - * @return the current TRANSACTION_* mode value - * @exception SQLException if a database access error occurs - */ - public int getTransactionIsolation() throws SQLException - { - String sql = "show transaction isolation level"; - String level = null; - if (haveMinimumServerVersion("7.3")) { - BaseResultSet rs = execSQL(sql); - if (rs.next()) { - level = rs.getString(1); - } - rs.close(); - } else { - BaseResultSet l_rs = execSQL(sql); - BaseStatement l_stat = l_rs.getPGStatement(); - SQLWarning warning = l_stat.getWarnings(); - if (warning != null) - { - level = warning.getMessage(); - } - l_rs.close(); - l_stat.close(); - } - if (level != null) { - level = level.toUpperCase(); - if (level.indexOf("READ COMMITTED") != -1) - return Connection.TRANSACTION_READ_COMMITTED; - else if (level.indexOf("READ UNCOMMITTED") != -1) - return Connection.TRANSACTION_READ_UNCOMMITTED; - else if (level.indexOf("REPEATABLE READ") != -1) - return Connection.TRANSACTION_REPEATABLE_READ; - else if (level.indexOf("SERIALIZABLE") != -1) - return Connection.TRANSACTION_SERIALIZABLE; - } - return Connection.TRANSACTION_READ_COMMITTED; - } - - /* - * You can call this method to try to change the transaction - * isolation level using one of the TRANSACTION_* values. - * - * <B>Note:</B> setTransactionIsolation cannot be called while - * in the middle of a transaction - * - * @param level one of the TRANSACTION_* isolation values with - * the exception of TRANSACTION_NONE; some databases may - * not support other values - * @exception SQLException if a database access error occurs - * @see java.sql.DatabaseMetaData#supportsTransactionIsolationLevel - */ - public void setTransactionIsolation(int level) throws SQLException - { - //In 7.1 and later versions of the server it is possible using - //the "set session" command to set this once for all future txns - //however in 7.0 and prior versions it is necessary to set it in - //each transaction, thus adding complexity below. - //When we decide to drop support for servers older than 7.1 - //this can be simplified - isolationLevel = level; - String isolationLevelSQL; - - if (!haveMinimumServerVersion("7.1")) - { - isolationLevelSQL = getIsolationLevelSQL(); - } - else - { - isolationLevelSQL = "SET SESSION CHARACTERISTICS AS TRANSACTION ISOLATION LEVEL "; - switch (isolationLevel) - { - case Connection.TRANSACTION_READ_COMMITTED: - isolationLevelSQL += "READ COMMITTED"; - break; - case Connection.TRANSACTION_SERIALIZABLE: - isolationLevelSQL += "SERIALIZABLE"; - break; - default: - throw new PSQLException("postgresql.con.isolevel", PSQLState.TRANSACTION_STATE_INVALID, - new Integer(isolationLevel)); - } - } - execSQL(isolationLevelSQL); - } - - /* - * Helper method used by setTransactionIsolation(), commit(), rollback() - * and setAutoCommit(). This returns the SQL string needed to - * set the isolation level for a transaction. In 7.1 and later it - * is possible to set a default isolation level that applies to all - * future transactions, this method is only necesary for 7.0 and older - * servers, and should be removed when support for these older - * servers are dropped - */ - protected String getIsolationLevelSQL() throws SQLException - { - //7.1 and higher servers have a default specified so - //no additional SQL is required to set the isolation level - if (haveMinimumServerVersion("7.1")) - { - return ""; - } - StringBuffer sb = new StringBuffer("SET TRANSACTION ISOLATION LEVEL"); - - switch (isolationLevel) - { - case Connection.TRANSACTION_READ_COMMITTED: - sb.append(" READ COMMITTED"); - break; - - case Connection.TRANSACTION_SERIALIZABLE: - sb.append(" SERIALIZABLE"); - break; - - default: - throw new PSQLException("postgresql.con.isolevel", PSQLState.TRANSACTION_STATE_INVALID, new Integer(isolationLevel)); - } - return sb.toString(); - } - - /* - * A sub-space of this Connection's database may be selected by - * setting a catalog name. If the driver does not support catalogs, - * it will silently ignore this request - * - * @exception SQLException if a database access error occurs - */ - public void setCatalog(String catalog) throws SQLException - { - //no-op - } - - /* - * Return the connections current catalog name, or null if no - * catalog name is set, or we dont support catalogs. - * - * @return the current catalog name or null - * @exception SQLException if a database access error occurs - */ - public String getCatalog() throws SQLException - { - return PG_DATABASE; - } - - /* - * Overides finalize(). If called, it closes the connection. - * - * This was done at the request of Rachel Greenham - * <[email protected]> who hit a problem where multiple - * clients didn't close the connection, and once a fortnight enough - * clients were open to kill the org.postgres server. - */ - public void finalize() throws Throwable - { - close(); - } - - private static String extractVersionNumber(String fullVersionString) - { - StringTokenizer versionParts = new StringTokenizer(fullVersionString); - versionParts.nextToken(); /* "PostgreSQL" */ - return versionParts.nextToken(); /* "X.Y.Z" */ - } - - /* - * Get server version number - */ - public String getDBVersionNumber() - { - return dbVersionNumber; - } - - // Parse a "dirty" integer surrounded by non-numeric characters - private static int integerPart(String dirtyString) - { - int start, end; - - for (start = 0; start < dirtyString.length() && !Character.isDigit(dirtyString.charAt(start)); ++start) - ; - - for (end = start; end < dirtyString.length() && Character.isDigit(dirtyString.charAt(end)); ++end) - ; - - if (start == end) - return 0; - - return Integer.parseInt(dirtyString.substring(start, end)); - } - - /* - * Get server major version - */ - public int getServerMajorVersion() - { - try - { - StringTokenizer versionTokens = new StringTokenizer(dbVersionNumber, "."); // aaXbb.ccYdd - return integerPart(versionTokens.nextToken()); // return X - } - catch (NoSuchElementException e) - { - return 0; - } - } - - /* - * Get server minor version - */ - public int getServerMinorVersion() - { - try - { - StringTokenizer versionTokens = new StringTokenizer(dbVersionNumber, "."); // aaXbb.ccYdd - versionTokens.nextToken(); // Skip aaXbb - return integerPart(versionTokens.nextToken()); // return Y - } - catch (NoSuchElementException e) - { - return 0; - } - } - - /** - * Is the server we are connected to running at least this version? - * This comparison method will fail whenever a major or minor version - * goes to two digits (10.3.0) or (7.10.1). - */ - public boolean haveMinimumServerVersion(String ver) throws SQLException - { - return (getDBVersionNumber().compareTo(ver) >= 0); - } - - /* - * This method returns true if the compatible level set in the connection - * (which can be passed into the connection or specified in the URL) - * is at least the value passed to this method. This is used to toggle - * between different functionality as it changes across different releases - * of the jdbc driver code. The values here are versions of the jdbc client - * and not server versions. For example in 7.1 get/setBytes worked on - * LargeObject values, in 7.2 these methods were changed to work on bytea - * values. This change in functionality could be disabled by setting the - * "compatible" level to be 7.1, in which case the driver will revert to - * the 7.1 functionality. - */ - public boolean haveMinimumCompatibleVersion(String ver) throws SQLException - { - return (compatible.compareTo(ver) >= 0); - } - - - /* - * This returns the java.sql.Types type for a PG type oid - * - * @param oid PostgreSQL type oid - * @return the java.sql.Types type - * @exception SQLException if a database access error occurs - */ - public int getSQLType(int oid) throws SQLException - { - Integer sqlType = (Integer)sqlTypeCache.get(new Integer(oid)); - - // it's not in the cache, so perform a query, and add the result to the cache - if (sqlType == null) - { - String pgType; - // The opaque type does not exist in the system catalogs. - if (oid == 0) { - pgType = "opaque"; - } else { - String sql; - if (haveMinimumServerVersion("7.3")) { - sql = "SELECT typname FROM pg_catalog.pg_type WHERE oid = " +oid; - } else { - sql = "SELECT typname FROM pg_type WHERE oid = " +oid; - } - BaseResultSet result = execSQL(sql); - if (result.getColumnCount() != 1 || result.getTupleCount() != 1) { - throw new PSQLException("postgresql.unexpected", PSQLState.UNEXPECTED_ERROR); - } - result.next(); - pgType = result.getString(1); - result.close(); - } - Integer iOid = new Integer(oid); - sqlType = new Integer(getSQLType(pgType)); - sqlTypeCache.put(iOid, sqlType); - pgTypeCache.put(iOid, pgType); - } - - return sqlType.intValue(); - } - - /* - * This returns the oid for a given PG data type - * @param typeName PostgreSQL type name - * @return PostgreSQL oid value for a field of this type - */ - public int getPGType(String typeName) throws SQLException - { - int oid = -1; - if (typeName != null) - { - Integer oidValue = (Integer) typeOidCache.get(typeName); - if (oidValue != null) - { - oid = oidValue.intValue(); - } - else - { - // it's not in the cache, so perform a query, and add the result to the cache - String sql; - if (haveMinimumServerVersion("7.3")) { - sql = "SELECT oid FROM pg_catalog.pg_type WHERE typname='" + typeName + "'"; - } else { - sql = "SELECT oid FROM pg_type WHERE typname='" + typeName + "'"; - } - BaseResultSet result = execSQL(sql); - if (result.getColumnCount() != 1 || result.getTupleCount() != 1) - throw new PSQLException("postgresql.unexpected", PSQLState.UNEXPECTED_ERROR); - result.next(); - oid = Integer.parseInt(result.getString(1)); - typeOidCache.put(typeName, new Integer(oid)); - result.close(); - } - } - return oid; - } - - /* - * We also need to get the PG type name as returned by the back end. - * - * @return the String representation of the type of this field - * @exception SQLException if a database access error occurs - */ - public String getPGType(int oid) throws SQLException - { - String pgType = (String) pgTypeCache.get(new Integer(oid)); - if (pgType == null) - { - getSQLType(oid); - pgType = (String) pgTypeCache.get(new Integer(oid)); - } - return pgType; - } - - //Because the get/setLogStream methods are deprecated in JDBC2 - //we use them for JDBC1 here and override this method in the jdbc2 - //version of this class - protected void enableDriverManagerLogging() - { - if (DriverManager.getLogStream() == null) - { - DriverManager.setLogStream(System.out); - } - } - - // This is a cache of the DatabaseMetaData instance for this connection - protected java.sql.DatabaseMetaData metadata; - - - /* - * Tests to see if a Connection is closed - * - * @return the status of the connection - * @exception SQLException (why?) - */ - public boolean isClosed() throws SQLException - { - return (pgStream == null); - } - - /* - * This implemetation uses the jdbc1Types array to support the jdbc1 - * datatypes. Basically jdbc1 and jdbc2 are the same, except that - * jdbc2 adds the Array types. - */ - public int getSQLType(String pgTypeName) - { - int sqlType = Types.OTHER; // default value - for (int i = 0;i < jdbc1Types.length;i++) - { - if (pgTypeName.equals(jdbc1Types[i])) - { - sqlType = jdbc1Typei[i]; - break; - } - } - return sqlType; - } - - /* - * This table holds the org.postgresql names for the types supported. - * Any types that map to Types.OTHER (eg POINT) don't go into this table. - * They default automatically to Types.OTHER - * - * Note: This must be in the same order as below. - * - * Tip: keep these grouped together by the Types. value - */ - private static final String jdbc1Types[] = { - "int2", - "int4", "oid", - "int8", - "cash", "money", - "numeric", - "float4", - "float8", - "bpchar", "char", "char2", "char4", "char8", "char16", - "varchar", "text", "name", "filename", - "bytea", - "bool", - "bit", - "date", - "time", - "abstime", "timestamp", "timestamptz" - }; - - /* - * This table holds the JDBC type for each entry above. - * - * Note: This must be in the same order as above - * - * Tip: keep these grouped together by the Types. value - */ - private static final int jdbc1Typei[] = { - Types.SMALLINT, - Types.INTEGER, Types.INTEGER, - Types.BIGINT, - Types.DOUBLE, Types.DOUBLE, - Types.NUMERIC, - Types.REAL, - Types.DOUBLE, - Types.CHAR, Types.CHAR, Types.CHAR, Types.CHAR, Types.CHAR, Types.CHAR, - Types.VARCHAR, Types.VARCHAR, Types.VARCHAR, Types.VARCHAR, - Types.BINARY, - Types.BIT, - Types.BIT, - Types.DATE, - Types.TIME, - Types.TIMESTAMP, Types.TIMESTAMP, Types.TIMESTAMP - }; - - public void cancelQuery() throws SQLException - { - org.postgresql.core.PGStream cancelStream = null; - try - { - cancelStream = new org.postgresql.core.PGStream(PG_HOST, PG_PORT); - } - catch (ConnectException cex) - { - // Added by Peter Mount <[email protected]> - // ConnectException is thrown when the connection cannot be made. - // we trap this an return a more meaningful message for the end user - throw new PSQLException ("postgresql.con.refused", PSQLState.CONNECTION_REJECTED); - } - catch (IOException e) - { - throw new PSQLException ("postgresql.con.failed", PSQLState.CONNECTION_UNABLE_TO_CONNECT, e); - } - - // Now we need to construct and send a cancel packet - try - { - cancelStream.SendInteger(16, 4); - cancelStream.SendInteger(80877102, 4); - cancelStream.SendInteger(pid, 4); - cancelStream.SendInteger(ckey, 4); - cancelStream.flush(); - } - catch (IOException e) - { - throw new PSQLException("postgresql.con.failed", PSQLState.CONNECTION_UNABLE_TO_CONNECT, e); - } - finally - { - try - { - if (cancelStream != null) - cancelStream.close(); - } - catch (IOException e) - {} // Ignore - } - } - - - //Methods to support postgres notifications - public void addNotification(org.postgresql.PGNotification p_notification) - { - if (m_notifications == null) - m_notifications = new Vector(); - m_notifications.addElement(p_notification); - } - - public PGNotification[] getNotifications() - { - PGNotification[] l_return = null; - if (m_notifications != null) - { - l_return = new PGNotification[m_notifications.size()]; - m_notifications.copyInto(l_return); - } - m_notifications = null; - return l_return; - } -} - - diff --git a/src/interfaces/jdbc/org/postgresql/jdbc1/AbstractJdbc1DatabaseMetaData.java b/src/interfaces/jdbc/org/postgresql/jdbc1/AbstractJdbc1DatabaseMetaData.java deleted file mode 100644 index d7161936904..00000000000 --- a/src/interfaces/jdbc/org/postgresql/jdbc1/AbstractJdbc1DatabaseMetaData.java +++ /dev/null @@ -1,3660 +0,0 @@ -package org.postgresql.jdbc1; - - -import java.sql.*; -import java.util.*; -import org.postgresql.core.BaseStatement; -import org.postgresql.core.Field; -import org.postgresql.core.Encoding; -import org.postgresql.util.PSQLException; -import org.postgresql.util.PSQLState; -import org.postgresql.Driver; - -public abstract class AbstractJdbc1DatabaseMetaData -{ - - private static final String keywords = "abort,acl,add,aggregate,append,archive," + - "arch_store,backward,binary,boolean,change,cluster," + - "copy,database,delimiter,delimiters,do,extend," + - "explain,forward,heavy,index,inherits,isnull," + - "light,listen,load,merge,nothing,notify," + - "notnull,oids,purge,rename,replace,retrieve," + - "returns,rule,recipe,setof,stdin,stdout,store," + - "vacuum,verbose,version"; - - protected AbstractJdbc1Connection connection; // The connection association - protected Encoding encoding; - - // These define various OID's. Hopefully they will stay constant. - protected static final int iVarcharOid = 1043; // OID for varchar - protected static final int iBoolOid = 16; // OID for bool - protected static final int iInt2Oid = 21; // OID for int2 - protected static final int iInt4Oid = 23; // OID for int4 - protected static final int VARHDRSZ = 4; // length for int4 - - private int NAMEDATALEN = 0; // length for name datatype - private int INDEX_MAX_KEYS = 0; // maximum number of keys in an index. - - protected int getMaxIndexKeys() throws SQLException { - if (INDEX_MAX_KEYS == 0) { - String from; - if (connection.haveMinimumServerVersion("7.3")) { - from = "pg_catalog.pg_namespace n, pg_catalog.pg_type t1, pg_catalog.pg_type t2 WHERE t1.typnamespace=n.oid AND n.nspname='pg_catalog' AND "; - } else { - from = "pg_type t1, pg_type t2 WHERE "; - } - String sql = "SELECT t1.typlen/t2.typlen FROM "+from+" t1.typelem=t2.oid AND t1.typname='oidvector'"; - ResultSet rs = connection.createStatement().executeQuery(sql); - if (!rs.next()) { - throw new PSQLException("postgresql.unexpected", PSQLState.UNEXPECTED_ERROR); - } - INDEX_MAX_KEYS = rs.getInt(1); - rs.close(); - } - return INDEX_MAX_KEYS; - } - - protected int getMaxNameLength() throws SQLException { - if (NAMEDATALEN == 0) { - String sql; - if (connection.haveMinimumServerVersion("7.3")) { - sql = "SELECT t.typlen FROM pg_catalog.pg_type t, pg_catalog.pg_namespace n WHERE t.typnamespace=n.oid AND t.typname='name' AND n.nspname='pg_catalog'"; - } else { - sql = "SELECT typlen FROM pg_type WHERE typname='name'"; - } - ResultSet rs = connection.createStatement().executeQuery(sql); - if (!rs.next()) { - throw new PSQLException("postgresql.unexpected", PSQLState.UNEXPECTED_ERROR); - } - NAMEDATALEN = rs.getInt("typlen"); - rs.close(); - } - return NAMEDATALEN - 1; - } - - public AbstractJdbc1DatabaseMetaData(AbstractJdbc1Connection conn) - { - this.connection = conn; - try { - this.encoding = conn.getEncoding(); - } - catch (SQLException sqle) { - this.encoding = Encoding.defaultEncoding(); - } - - } - - /* - * Can all the procedures returned by getProcedures be called - * by the current user? - * - * @return true if so - * @exception SQLException if a database access error occurs - */ - public boolean allProceduresAreCallable() throws SQLException - { - if (Driver.logDebug) - Driver.debug("allProceduresAreCallable"); - return true; // For now... - } - - /* - * Can all the tables returned by getTable be SELECTed by - * the current user? - * - * @return true if so - * @exception SQLException if a database access error occurs - */ - public boolean allTablesAreSelectable() throws SQLException - { - if (Driver.logDebug) - Driver.debug("allTablesAreSelectable"); - return true; // For now... - } - - /* - * What is the URL for this database? - * - * @return the url or null if it cannott be generated - * @exception SQLException if a database access error occurs - */ - public String getURL() throws SQLException - { - String url = connection.getURL(); - if (Driver.logDebug) - Driver.debug("getURL " + url); - return url; - } - - /* - * What is our user name as known to the database? - * - * @return our database user name - * @exception SQLException if a database access error occurs - */ - public String getUserName() throws SQLException - { - String userName = connection.getUserName(); - if (Driver.logDebug) - Driver.debug("getUserName " + userName); - return userName; - } - - /* - * Is the database in read-only mode? - * - * @return true if so - * @exception SQLException if a database access error occurs - */ - public boolean isReadOnly() throws SQLException - { - boolean isReadOnly = connection.isReadOnly(); - if (Driver.logDebug) - Driver.debug("isReadOnly " + isReadOnly); - return isReadOnly; - } - - /* - * Are NULL values sorted high? - * - * @return true if so - * @exception SQLException if a database access error occurs - */ - public boolean nullsAreSortedHigh() throws SQLException - { - boolean nullSortedHigh = connection.haveMinimumServerVersion("7.2"); - if (Driver.logDebug) - Driver.debug("nullsAreSortedHigh " + nullSortedHigh); - return nullSortedHigh; - } - - /* - * Are NULL values sorted low? - * - * @return true if so - * @exception SQLException if a database access error occurs - */ - public boolean nullsAreSortedLow() throws SQLException - { - if (Driver.logDebug) - Driver.debug("nullsAreSortedLow false"); - return false; - } - - /* - * Are NULL values sorted at the start regardless of sort order? - * - * @return true if so - * @exception SQLException if a database access error occurs - */ - public boolean nullsAreSortedAtStart() throws SQLException - { - if (Driver.logDebug) - Driver.debug("nullsAreSortedAtStart false"); - return false; - } - - /* - * Are NULL values sorted at the end regardless of sort order? - * - * @return true if so - * @exception SQLException if a database access error occurs - */ - public boolean nullsAreSortedAtEnd() throws SQLException - { - boolean nullsAreSortedAtEnd = ! connection.haveMinimumServerVersion("7.2"); - if (Driver.logDebug) - Driver.debug("nullsAreSortedAtEnd " + nullsAreSortedAtEnd); - return nullsAreSortedAtEnd; - } - - /* - * What is the name of this database product - we hope that it is - * PostgreSQL, so we return that explicitly. - * - * @return the database product name - * @exception SQLException if a database access error occurs - */ - public String getDatabaseProductName() throws SQLException - { - if (Driver.logDebug) - Driver.debug("getDatabaseProductName PostgresSQL"); - return "PostgreSQL"; - } - - /* - * What is the version of this database product. - * - * @return the database version - * @exception SQLException if a database access error occurs - */ - public String getDatabaseProductVersion() throws SQLException - { - String versionNumber = connection.getDBVersionNumber(); - if (Driver.logDebug) - Driver.debug("getDatabaseProductVersion " + versionNumber); - return versionNumber; - } - - /* - * What is the name of this JDBC driver? If we don't know this - * we are doing something wrong! - * - * @return the JDBC driver name - * @exception SQLException why? - */ - public String getDriverName() throws SQLException - { - String driverName = "PostgreSQL Native Driver"; - if (Driver.logDebug) - Driver.debug("getDriverName" + driverName); - return driverName; - } - - /* - * What is the version string of this JDBC driver? Again, this is - * static. - * - * @return the JDBC driver name. - * @exception SQLException why? - */ - public String getDriverVersion() throws SQLException - { - String driverVersion = Driver.getVersion(); - if (Driver.logDebug) - Driver.debug("getDriverVersion " + driverVersion); - return driverVersion; - } - - /* - * What is this JDBC driver's major version number? - * - * @return the JDBC driver major version - */ - public int getDriverMajorVersion() - { - int majorVersion = connection.this_driver.getMajorVersion(); - if (Driver.logDebug) - Driver.debug("getMajorVersion " + majorVersion); - return majorVersion; - } - - /* - * What is this JDBC driver's minor version number? - * - * @return the JDBC driver minor version - */ - public int getDriverMinorVersion() - { - int minorVersion = connection.this_driver.getMinorVersion(); - if (Driver.logDebug) - Driver.debug("getMinorVersion " + minorVersion); - return minorVersion; - } - - /* - * Does the database store tables in a local file? No - it - * stores them in a file on the server. - * - * @return true if so - * @exception SQLException if a database access error occurs - */ - public boolean usesLocalFiles() throws SQLException - { - if (Driver.logDebug) - Driver.debug("usesLocalFiles " + false); - return false; - } - - /* - * Does the database use a file for each table? Well, not really, - * since it doesnt use local files. - * - * @return true if so - * @exception SQLException if a database access error occurs - */ - public boolean usesLocalFilePerTable() throws SQLException - { - if (Driver.logDebug) - Driver.debug("usesLocalFilePerTable " + false); - return false; - } - - /* - * Does the database treat mixed case unquoted SQL identifiers - * as case sensitive and as a result store them in mixed case? - * A JDBC-Compliant driver will always return false. - * - * @return true if so - * @exception SQLException if a database access error occurs - */ - public boolean supportsMixedCaseIdentifiers() throws SQLException - { - if (Driver.logDebug) - Driver.debug("supportsMixedCaseIdentifiers " + false); - return false; - } - - /* - * Does the database treat mixed case unquoted SQL identifiers as - * case insensitive and store them in upper case? - * - * @return true if so - */ - public boolean storesUpperCaseIdentifiers() throws SQLException - { - if (Driver.logDebug) - Driver.debug("storesUpperCaseIdentifiers " + false); - return false; - } - - /* - * Does the database treat mixed case unquoted SQL identifiers as - * case insensitive and store them in lower case? - * - * @return true if so - */ - public boolean storesLowerCaseIdentifiers() throws SQLException - { - if (Driver.logDebug) - Driver.debug("storesLowerCaseIdentifiers " + true); - return true; - } - - /* - * Does the database treat mixed case unquoted SQL identifiers as - * case insensitive and store them in mixed case? - * - * @return true if so - */ - public boolean storesMixedCaseIdentifiers() throws SQLException - { - if (Driver.logDebug) - Driver.debug("storesMixedCaseIdentifiers " + false); - return false; - } - - /* - * Does the database treat mixed case quoted SQL identifiers as - * case sensitive and as a result store them in mixed case? A - * JDBC compliant driver will always return true. - * - * @return true if so - * @exception SQLException if a database access error occurs - */ - public boolean supportsMixedCaseQuotedIdentifiers() throws SQLException - { - if (Driver.logDebug) - Driver.debug("supportsMixedCaseQuotedIdentifiers " + true); - return true; - } - - /* - * Does the database treat mixed case quoted SQL identifiers as - * case insensitive and store them in upper case? - * - * @return true if so - */ - public boolean storesUpperCaseQuotedIdentifiers() throws SQLException - { - if (Driver.logDebug) - Driver.debug("storesUpperCaseQuotedIdentifiers " + false); - return false; - } - - /* - * Does the database treat mixed case quoted SQL identifiers as case - * insensitive and store them in lower case? - * - * @return true if so - */ - public boolean storesLowerCaseQuotedIdentifiers() throws SQLException - { - if (Driver.logDebug) - Driver.debug("storesLowerCaseQuotedIdentifiers " + false); - return false; - } - - /* - * Does the database treat mixed case quoted SQL identifiers as case - * insensitive and store them in mixed case? - * - * @return true if so - */ - public boolean storesMixedCaseQuotedIdentifiers() throws SQLException - { - if (Driver.logDebug) - Driver.debug("storesMixedCaseQuotedIdentifiers " + false); - return false; - } - - /* - * What is the string used to quote SQL identifiers? This returns - * a space if identifier quoting isn't supported. A JDBC Compliant - * driver will always use a double quote character. - * - * @return the quoting string - * @exception SQLException if a database access error occurs - */ - public String getIdentifierQuoteString() throws SQLException - { - if (Driver.logDebug) - Driver.debug("getIdentifierQuoteString \"" ); - return "\""; - } - - /* - * Get a comma separated list of all a database's SQL keywords that - * are NOT also SQL92 keywords. - * - * <p>Within PostgreSQL, the keywords are found in - * src/backend/parser/keywords.c - * - * <p>For SQL Keywords, I took the list provided at - * <a href="http://web.dementia.org/~shadow/sql/sql3bnf.sep93.txt"> - * http://web.dementia.org/~shadow/sql/sql3bnf.sep93.txt</a> - * which is for SQL3, not SQL-92, but it is close enough for - * this purpose. - * - * @return a comma separated list of keywords we use - * @exception SQLException if a database access error occurs - */ - public String getSQLKeywords() throws SQLException - { - return keywords; - } - - public String getNumericFunctions() throws SQLException - { - if (Driver.logDebug) - Driver.debug("getNumericFunctions"); - return ""; - } - - public String getStringFunctions() throws SQLException - { - if (Driver.logDebug) - Driver.debug("getStringFunctions"); - return ""; - } - - public String getSystemFunctions() throws SQLException - { - if (Driver.logDebug) - Driver.debug("getSystemFunctions"); - return ""; - } - - public String getTimeDateFunctions() throws SQLException - { - if (Driver.logDebug) - Driver.debug("getTimeDateFunctions"); - return ""; - } - - /* - * This is the string that can be used to escape '_' and '%' in - * a search string pattern style catalog search parameters - * - * @return the string used to escape wildcard characters - * @exception SQLException if a database access error occurs - */ - public String getSearchStringEscape() throws SQLException - { - if (Driver.logDebug) - Driver.debug("getSearchStringEscape"); - return "\\"; - } - - /* - * Get all the "extra" characters that can be used in unquoted - * identifier names (those beyond a-zA-Z0-9 and _) - * - * <p>From the file src/backend/parser/scan.l, an identifier is - * {letter}{letter_or_digit} which makes it just those listed - * above. - * - * @return a string containing the extra characters - * @exception SQLException if a database access error occurs - */ - public String getExtraNameCharacters() throws SQLException - { - if (Driver.logDebug) - Driver.debug("getExtraNameCharacters"); - return ""; - } - - /* - * Is "ALTER TABLE" with an add column supported? - * Yes for PostgreSQL 6.1 - * - * @return true if so - * @exception SQLException if a database access error occurs - */ - public boolean supportsAlterTableWithAddColumn() throws SQLException - { - if (Driver.logDebug) - Driver.debug("supportsAlterTableWithAddColumn " + true); - return true; - } - - /* - * Is "ALTER TABLE" with a drop column supported? - * - * @return true if so - * @exception SQLException if a database access error occurs - */ - public boolean supportsAlterTableWithDropColumn() throws SQLException - { - boolean dropColumn = connection.haveMinimumServerVersion("7.3"); - if (Driver.logDebug) - Driver.debug("supportsAlterTableWithDropColumn " + dropColumn); - return dropColumn; - } - - /* - * Is column aliasing supported? - * - * <p>If so, the SQL AS clause can be used to provide names for - * computed columns or to provide alias names for columns as - * required. A JDBC Compliant driver always returns true. - * - * <p>e.g. - * - * <br><pre> - * select count(C) as C_COUNT from T group by C; - * - * </pre><br> - * should return a column named as C_COUNT instead of count(C) - * - * @return true if so - * @exception SQLException if a database access error occurs - */ - public boolean supportsColumnAliasing() throws SQLException - { - if (Driver.logDebug) - Driver.debug("supportsColumnAliasing " + true); - return true; - } - - /* - * Are concatenations between NULL and non-NULL values NULL? A - * JDBC Compliant driver always returns true - * - * @return true if so - * @exception SQLException if a database access error occurs - */ - public boolean nullPlusNonNullIsNull() throws SQLException - { - if (Driver.logDebug) - Driver.debug("nullPlusNonNullIsNull " + true); - return true; - } - - public boolean supportsConvert() throws SQLException - { - if (Driver.logDebug) - Driver.debug("supportsConvert " + false); - return false; - } - - public boolean supportsConvert(int fromType, int toType) throws SQLException - { - if (Driver.logDebug) - Driver.debug("supportsConvert " + false); - return false; - } - - /* - * Are table correlation names supported? A JDBC Compliant - * driver always returns true. - * - * @return true if so; false otherwise - * @exception SQLException - if a database access error occurs - */ - public boolean supportsTableCorrelationNames() throws SQLException - { - if (Driver.logDebug) - Driver.debug("supportsTableCorrelationNames " + true); - return true; - } - - /* - * If table correlation names are supported, are they restricted to - * be different from the names of the tables? - * - * @return true if so; false otherwise - * @exception SQLException - if a database access error occurs - */ - public boolean supportsDifferentTableCorrelationNames() throws SQLException - { - if (Driver.logDebug) - Driver.debug("supportsDifferentTableCorrelationNames " + false); - return false; - } - - /* - * Are expressions in "ORDER BY" lists supported? - * - * <br>e.g. select * from t order by a + b; - * - * @return true if so - * @exception SQLException if a database access error occurs - */ - public boolean supportsExpressionsInOrderBy() throws SQLException - { - if (Driver.logDebug) - Driver.debug("supportsExpressionsInOrderBy " + true); - return true; - } - - /* - * Can an "ORDER BY" clause use columns not in the SELECT? - * - * @return true if so - * @exception SQLException if a database access error occurs - */ - public boolean supportsOrderByUnrelated() throws SQLException - { - boolean supportsOrderByUnrelated = connection.haveMinimumServerVersion("6.4"); - if (Driver.logDebug) - Driver.debug("supportsOrderByUnrelated " + supportsOrderByUnrelated); - return supportsOrderByUnrelated; - } - - /* - * Is some form of "GROUP BY" clause supported? - * I checked it, and yes it is. - * - * @return true if so - * @exception SQLException if a database access error occurs - */ - public boolean supportsGroupBy() throws SQLException - { - if (Driver.logDebug) - Driver.debug("supportsGroupBy " + true); - return true; - } - - /* - * Can a "GROUP BY" clause use columns not in the SELECT? - * - * @return true if so - * @exception SQLException if a database access error occurs - */ - public boolean supportsGroupByUnrelated() throws SQLException - { - boolean supportsGroupByUnrelated = connection.haveMinimumServerVersion("6.4"); - if (Driver.logDebug) - Driver.debug("supportsGroupByUnrelated " + supportsGroupByUnrelated); - return supportsGroupByUnrelated; - } - - /* - * Can a "GROUP BY" clause add columns not in the SELECT provided - * it specifies all the columns in the SELECT? Does anyone actually - * understand what they mean here? - * - * (I think this is a subset of the previous function. -- petere) - * - * @return true if so - * @exception SQLException if a database access error occurs - */ - public boolean supportsGroupByBeyondSelect() throws SQLException - { - boolean supportsGroupByBeyondSelect = connection.haveMinimumServerVersion("6.4"); - if (Driver.logDebug) - Driver.debug("supportsGroupByUnrelated " + supportsGroupByBeyondSelect); - return supportsGroupByBeyondSelect; - } - - /* - * Is the escape character in "LIKE" clauses supported? A - * JDBC compliant driver always returns true. - * - * @return true if so - * @exception SQLException if a database access error occurs - */ - public boolean supportsLikeEscapeClause() throws SQLException - { - boolean supportsLikeEscapeClause = connection.haveMinimumServerVersion("7.1"); - if (Driver.logDebug) - Driver.debug("supportsLikeEscapeClause " + supportsLikeEscapeClause); - return supportsLikeEscapeClause; - } - - /* - * Are multiple ResultSets from a single execute supported? - * Well, I implemented it, but I dont think this is possible from - * the back ends point of view. - * - * @return true if so - * @exception SQLException if a database access error occurs - */ - public boolean supportsMultipleResultSets() throws SQLException - { - if (Driver.logDebug) - Driver.debug("supportsMultipleResultSets " + false); - return false; - } - - /* - * Can we have multiple transactions open at once (on different - * connections?) - * I guess we can have, since Im relying on it. - * - * @return true if so - * @exception SQLException if a database access error occurs - */ - public boolean supportsMultipleTransactions() throws SQLException - { - if (Driver.logDebug) - Driver.debug("supportsMultipleTransactions " + true); - return true; - } - - /* - * Can columns be defined as non-nullable. A JDBC Compliant driver - * always returns true. - * - * <p>This changed from false to true in v6.2 of the driver, as this - * support was added to the backend. - * - * @return true if so - * @exception SQLException if a database access error occurs - */ - public boolean supportsNonNullableColumns() throws SQLException - { - if (Driver.logDebug) - Driver.debug("supportsNonNullableColumns true"); - return true; - } - - /* - * Does this driver support the minimum ODBC SQL grammar. This - * grammar is defined at: - * - * <p><a href="http://www.microsoft.com/msdn/sdk/platforms/doc/odbc/src/intropr.htm">http://www.microsoft.com/msdn/sdk/platforms/doc/odbc/src/intropr.htm</a> - * - * <p>In Appendix C. From this description, we seem to support the - * ODBC minimal (Level 0) grammar. - * - * @return true if so - * @exception SQLException if a database access error occurs - */ - public boolean supportsMinimumSQLGrammar() throws SQLException - { - if (Driver.logDebug) - Driver.debug("supportsMinimumSQLGrammar TRUE"); - return true; - } - - /* - * Does this driver support the Core ODBC SQL grammar. We need - * SQL-92 conformance for this. - * - * @return true if so - * @exception SQLException if a database access error occurs - */ - public boolean supportsCoreSQLGrammar() throws SQLException - { - if (Driver.logDebug) - Driver.debug("supportsCoreSQLGrammar FALSE "); - return false; - } - - /* - * Does this driver support the Extended (Level 2) ODBC SQL - * grammar. We don't conform to the Core (Level 1), so we can't - * conform to the Extended SQL Grammar. - * - * @return true if so - * @exception SQLException if a database access error occurs - */ - public boolean supportsExtendedSQLGrammar() throws SQLException - { - if (Driver.logDebug) - Driver.debug("supportsExtendedSQLGrammar FALSE"); - return false; - } - - /* - * Does this driver support the ANSI-92 entry level SQL grammar? - * All JDBC Compliant drivers must return true. We currently - * report false until 'schema' support is added. Then this - * should be changed to return true, since we will be mostly - * compliant (probably more compliant than many other databases) - * And since this is a requirement for all JDBC drivers we - * need to get to the point where we can return true. - * - * @return true if so - * @exception SQLException if a database access error occurs - */ - public boolean supportsANSI92EntryLevelSQL() throws SQLException - { - boolean schemas = connection.haveMinimumServerVersion("7.3"); - if (Driver.logDebug) - Driver.debug("supportsANSI92EntryLevelSQL " + schemas); - return schemas; - } - - /* - * Does this driver support the ANSI-92 intermediate level SQL - * grammar? - * - * @return true if so - * @exception SQLException if a database access error occurs - */ - public boolean supportsANSI92IntermediateSQL() throws SQLException - { - if (Driver.logDebug) - Driver.debug("supportsANSI92IntermediateSQL false "); - return false; - } - - /* - * Does this driver support the ANSI-92 full SQL grammar? - * - * @return true if so - * @exception SQLException if a database access error occurs - */ - public boolean supportsANSI92FullSQL() throws SQLException - { - if (Driver.logDebug) - Driver.debug("supportsANSI92FullSQL false "); - return false; - } - - /* - * Is the SQL Integrity Enhancement Facility supported? - * Our best guess is that this means support for constraints - * - * @return true if so - * @exception SQLException if a database access error occurs - */ - public boolean supportsIntegrityEnhancementFacility() throws SQLException - { - if (Driver.logDebug) - Driver.debug("supportsIntegrityEnhancementFacility true "); - return true; - } - - /* - * Is some form of outer join supported? - * - * @return true if so - * @exception SQLException if a database access error occurs - */ - public boolean supportsOuterJoins() throws SQLException - { - boolean supportsOuterJoins = connection.haveMinimumServerVersion("7.1"); - if (Driver.logDebug) - Driver.debug("supportsOuterJoins " + supportsOuterJoins); - return supportsOuterJoins; - } - - /* - * Are full nexted outer joins supported? - * - * @return true if so - * @exception SQLException if a database access error occurs - */ - public boolean supportsFullOuterJoins() throws SQLException - { - boolean supportsFullOuterJoins = connection.haveMinimumServerVersion("7.1"); - if (Driver.logDebug) - Driver.debug("supportsFullOuterJoins " + supportsFullOuterJoins); - return supportsFullOuterJoins; - } - - /* - * Is there limited support for outer joins? - * - * @return true if so - * @exception SQLException if a database access error occurs - */ - public boolean supportsLimitedOuterJoins() throws SQLException - { - boolean supportsLimitedOuterJoins = connection.haveMinimumServerVersion("7.1"); - if (Driver.logDebug) - Driver.debug("supportsFullOuterJoins " + supportsLimitedOuterJoins); - return supportsLimitedOuterJoins; - } - - /* - * What is the database vendor's preferred term for "schema"? - * PostgreSQL doesn't have schemas, but when it does, we'll use the - * term "schema". - * - * @return the vendor term - * @exception SQLException if a database access error occurs - */ - public String getSchemaTerm() throws SQLException - { - if (Driver.logDebug) - Driver.debug("getSchemaTerm schema"); - return "schema"; - } - - /* - * What is the database vendor's preferred term for "procedure"? - * Traditionally, "function" has been used. - * - * @return the vendor term - * @exception SQLException if a database access error occurs - */ - public String getProcedureTerm() throws SQLException - { - if (Driver.logDebug) - Driver.debug("getProcedureTerm function "); - return "function"; - } - - /* - * What is the database vendor's preferred term for "catalog"? - * - * @return the vendor term - * @exception SQLException if a database access error occurs - */ - public String getCatalogTerm() throws SQLException - { - if (Driver.logDebug) - Driver.debug("getCatalogTerm database "); - return "database"; - } - - /* - * Does a catalog appear at the start of a qualified table name? - * (Otherwise it appears at the end). - * - * @return true if so - * @exception SQLException if a database access error occurs - */ - public boolean isCatalogAtStart() throws SQLException - { - // return true here; we return false for every other catalog function - // so it won't matter what we return here D.C. - if (Driver.logDebug) - Driver.debug("isCatalogAtStart not implemented"); - return true; - } - - /* - * What is the Catalog separator. - * - * @return the catalog separator string - * @exception SQLException if a database access error occurs - */ - public String getCatalogSeparator() throws SQLException - { - // Give them something to work with here - // everything else returns false so it won't matter what we return here D.C. - if (Driver.logDebug) - Driver.debug("getCatalogSeparator not implemented "); - return "."; - } - - /* - * Can a schema name be used in a data manipulation statement? - * - * @return true if so - * @exception SQLException if a database access error occurs - */ - public boolean supportsSchemasInDataManipulation() throws SQLException - { - boolean schemas = connection.haveMinimumServerVersion("7.3"); - if (Driver.logDebug) - Driver.debug("supportsSchemasInDataManipulation "+schemas); - return schemas; - } - - /* - * Can a schema name be used in a procedure call statement? - * - * @return true if so - * @exception SQLException if a database access error occurs - */ - public boolean supportsSchemasInProcedureCalls() throws SQLException - { - boolean schemas = connection.haveMinimumServerVersion("7.3"); - if (Driver.logDebug) - Driver.debug("supportsSchemasInProcedureCalls "+schemas); - return schemas; - } - - /* - * Can a schema be used in a table definition statement? - * - * @return true if so - * @exception SQLException if a database access error occurs - */ - public boolean supportsSchemasInTableDefinitions() throws SQLException - { - boolean schemas = connection.haveMinimumServerVersion("7.3"); - - if (Driver.logDebug) - Driver.debug("supportsSchemasInTableDefinitions " + schemas); - return schemas; - } - - /* - * Can a schema name be used in an index definition statement? - * - * @return true if so - * @exception SQLException if a database access error occurs - */ - public boolean supportsSchemasInIndexDefinitions() throws SQLException - { - boolean schemas = connection.haveMinimumServerVersion("7.3"); - if (Driver.logDebug) - Driver.debug("supportsSchemasInIndexDefinitions "+schemas); - return schemas; - } - - /* - * Can a schema name be used in a privilege definition statement? - * - * @return true if so - * @exception SQLException if a database access error occurs - */ - public boolean supportsSchemasInPrivilegeDefinitions() throws SQLException - { - boolean schemas = connection.haveMinimumServerVersion("7.3"); - if (Driver.logDebug) - Driver.debug("supportsSchemasInPrivilegeDefinitions "+schemas); - return schemas; - } - - /* - * Can a catalog name be used in a data manipulation statement? - * - * @return true if so - * @exception SQLException if a database access error occurs - */ - public boolean supportsCatalogsInDataManipulation() throws SQLException - { - if (Driver.logDebug) - Driver.debug("supportsCatalogsInDataManipulation false"); - return false; - } - - /* - * Can a catalog name be used in a procedure call statement? - * - * @return true if so - * @exception SQLException if a database access error occurs - */ - public boolean supportsCatalogsInProcedureCalls() throws SQLException - { - if (Driver.logDebug) - Driver.debug("supportsCatalogsInDataManipulation false"); - return false; - } - - /* - * Can a catalog name be used in a table definition statement? - * - * @return true if so - * @exception SQLException if a database access error occurs - */ - public boolean supportsCatalogsInTableDefinitions() throws SQLException - { - if (Driver.logDebug) - Driver.debug("supportsCatalogsInTableDefinitions false"); - return false; - } - - /* - * Can a catalog name be used in an index definition? - * - * @return true if so - * @exception SQLException if a database access error occurs - */ - public boolean supportsCatalogsInIndexDefinitions() throws SQLException - { - if (Driver.logDebug) - Driver.debug("supportsCatalogsInIndexDefinitions false"); - return false; - } - - /* - * Can a catalog name be used in a privilege definition statement? - * - * @return true if so - * @exception SQLException if a database access error occurs - */ - public boolean supportsCatalogsInPrivilegeDefinitions() throws SQLException - { - if (Driver.logDebug) - Driver.debug("supportsCatalogsInPrivilegeDefinitions false"); - return false; - } - - /* - * We support cursors for gets only it seems. I dont see a method - * to get a positioned delete. - * - * @return true if so - * @exception SQLException if a database access error occurs - */ - public boolean supportsPositionedDelete() throws SQLException - { - if (Driver.logDebug) - Driver.debug("supportsPositionedDelete false"); - return false; // For now... - } - - /* - * Is positioned UPDATE supported? - * - * @return true if so - * @exception SQLException if a database access error occurs - */ - public boolean supportsPositionedUpdate() throws SQLException - { - if (Driver.logDebug) - Driver.debug("supportsPositionedUpdate false"); - return false; // For now... - } - - /* - * Is SELECT for UPDATE supported? - * - * @return true if so; false otherwise - * @exception SQLException - if a database access error occurs - */ - public boolean supportsSelectForUpdate() throws SQLException - { - return connection.haveMinimumServerVersion("6.5"); - } - - /* - * Are stored procedure calls using the stored procedure escape - * syntax supported? - * - * @return true if so; false otherwise - * @exception SQLException - if a database access error occurs - */ - public boolean supportsStoredProcedures() throws SQLException - { - return false; - } - - /* - * Are subqueries in comparison expressions supported? A JDBC - * Compliant driver always returns true. - * - * @return true if so; false otherwise - * @exception SQLException - if a database access error occurs - */ - public boolean supportsSubqueriesInComparisons() throws SQLException - { - return true; - } - - /* - * Are subqueries in 'exists' expressions supported? A JDBC - * Compliant driver always returns true. - * - * @return true if so; false otherwise - * @exception SQLException - if a database access error occurs - */ - public boolean supportsSubqueriesInExists() throws SQLException - { - return true; - } - - /* - * Are subqueries in 'in' statements supported? A JDBC - * Compliant driver always returns true. - * - * @return true if so; false otherwise - * @exception SQLException - if a database access error occurs - */ - public boolean supportsSubqueriesInIns() throws SQLException - { - return true; - } - - /* - * Are subqueries in quantified expressions supported? A JDBC - * Compliant driver always returns true. - * - * (No idea what this is, but we support a good deal of - * subquerying.) - * - * @return true if so; false otherwise - * @exception SQLException - if a database access error occurs - */ - public boolean supportsSubqueriesInQuantifieds() throws SQLException - { - return true; - } - - /* - * Are correlated subqueries supported? A JDBC Compliant driver - * always returns true. - * - * (a.k.a. subselect in from?) - * - * @return true if so; false otherwise - * @exception SQLException - if a database access error occurs - */ - public boolean supportsCorrelatedSubqueries() throws SQLException - { - return connection.haveMinimumServerVersion("7.1"); - } - - /* - * Is SQL UNION supported? - * - * @return true if so - * @exception SQLException if a database access error occurs - */ - public boolean supportsUnion() throws SQLException - { - return true; // since 6.3 - } - - /* - * Is SQL UNION ALL supported? - * - * @return true if so - * @exception SQLException if a database access error occurs - */ - public boolean supportsUnionAll() throws SQLException - { - return connection.haveMinimumServerVersion("7.1"); - } - - /* - * In PostgreSQL, Cursors are only open within transactions. - * - * @return true if so - * @exception SQLException if a database access error occurs - */ - public boolean supportsOpenCursorsAcrossCommit() throws SQLException - { - return false; - } - - /* - * Do we support open cursors across multiple transactions? - * - * @return true if so - * @exception SQLException if a database access error occurs - */ - public boolean supportsOpenCursorsAcrossRollback() throws SQLException - { - return false; - } - - /* - * Can statements remain open across commits? They may, but - * this driver cannot guarentee that. In further reflection. - * we are talking a Statement object here, so the answer is - * yes, since the Statement is only a vehicle to ExecSQL() - * - * @return true if they always remain open; false otherwise - * @exception SQLException if a database access error occurs - */ - public boolean supportsOpenStatementsAcrossCommit() throws SQLException - { - return true; - } - - /* - * Can statements remain open across rollbacks? They may, but - * this driver cannot guarentee that. In further contemplation, - * we are talking a Statement object here, so the answer is yes, - * since the Statement is only a vehicle to ExecSQL() in Connection - * - * @return true if they always remain open; false otherwise - * @exception SQLException if a database access error occurs - */ - public boolean supportsOpenStatementsAcrossRollback() throws SQLException - { - return true; - } - - /* - * How many hex characters can you have in an inline binary literal - * - * @return the max literal length - * @exception SQLException if a database access error occurs - */ - public int getMaxBinaryLiteralLength() throws SQLException - { - return 0; // no limit - } - - /* - * What is the maximum length for a character literal - * I suppose it is 8190 (8192 - 2 for the quotes) - * - * @return the max literal length - * @exception SQLException if a database access error occurs - */ - public int getMaxCharLiteralLength() throws SQLException - { - return 0; // no limit - } - - /* - * Whats the limit on column name length. - * - * @return the maximum column name length - * @exception SQLException if a database access error occurs - */ - public int getMaxColumnNameLength() throws SQLException - { - return getMaxNameLength(); - } - - /* - * What is the maximum number of columns in a "GROUP BY" clause? - * - * @return the max number of columns - * @exception SQLException if a database access error occurs - */ - public int getMaxColumnsInGroupBy() throws SQLException - { - return 0; // no limit - } - - /* - * What's the maximum number of columns allowed in an index? - * - * @return max number of columns - * @exception SQLException if a database access error occurs - */ - public int getMaxColumnsInIndex() throws SQLException - { - return getMaxIndexKeys(); - } - - /* - * What's the maximum number of columns in an "ORDER BY clause? - * - * @return the max columns - * @exception SQLException if a database access error occurs - */ - public int getMaxColumnsInOrderBy() throws SQLException - { - return 0; // no limit - } - - /* - * What is the maximum number of columns in a "SELECT" list? - * - * @return the max columns - * @exception SQLException if a database access error occurs - */ - public int getMaxColumnsInSelect() throws SQLException - { - return 0; // no limit - } - - /* - * What is the maximum number of columns in a table? From the - * CREATE TABLE reference page... - * - * <p>"The new class is created as a heap with no initial data. A - * class can have no more than 1600 attributes (realistically, - * this is limited by the fact that tuple sizes must be less than - * 8192 bytes)..." - * - * @return the max columns - * @exception SQLException if a database access error occurs - */ - public int getMaxColumnsInTable() throws SQLException - { - return 1600; - } - - /* - * How many active connection can we have at a time to this - * database? Well, since it depends on postmaster, which just - * does a listen() followed by an accept() and fork(), its - * basically very high. Unless the system runs out of processes, - * it can be 65535 (the number of aux. ports on a TCP/IP system). - * I will return 8192 since that is what even the largest system - * can realistically handle, - * - * @return the maximum number of connections - * @exception SQLException if a database access error occurs - */ - public int getMaxConnections() throws SQLException - { - return 8192; - } - - /* - * What is the maximum cursor name length - * - * @return max cursor name length in bytes - * @exception SQLException if a database access error occurs - */ - public int getMaxCursorNameLength() throws SQLException - { - return getMaxNameLength(); - } - - /* - * Retrieves the maximum number of bytes for an index, including all - * of the parts of the index. - * - * @return max index length in bytes, which includes the composite - * of all the constituent parts of the index; a result of zero means - * that there is no limit or the limit is not known - * @exception SQLException if a database access error occurs - */ - public int getMaxIndexLength() throws SQLException - { - return 0; // no limit (larger than an int anyway) - } - - public int getMaxSchemaNameLength() throws SQLException - { - return getMaxNameLength(); - } - - /* - * What is the maximum length of a procedure name - * - * @return the max name length in bytes - * @exception SQLException if a database access error occurs - */ - public int getMaxProcedureNameLength() throws SQLException - { - return getMaxNameLength(); - } - - public int getMaxCatalogNameLength() throws SQLException - { - return getMaxNameLength(); - } - - /* - * What is the maximum length of a single row? - * - * @return max row size in bytes - * @exception SQLException if a database access error occurs - */ - public int getMaxRowSize() throws SQLException - { - if (connection.haveMinimumServerVersion("7.1")) - return 1073741824; // 1 GB - else - return 8192; // XXX could be altered - } - - /* - * Did getMaxRowSize() include LONGVARCHAR and LONGVARBINARY - * blobs? We don't handle blobs yet - * - * @return true if so - * @exception SQLException if a database access error occurs - */ - public boolean doesMaxRowSizeIncludeBlobs() throws SQLException - { - return false; - } - - /* - * What is the maximum length of a SQL statement? - * - * @return max length in bytes - * @exception SQLException if a database access error occurs - */ - public int getMaxStatementLength() throws SQLException - { - if (connection.haveMinimumServerVersion("7.0")) - return 0; // actually whatever fits in size_t - else - return 16384; - } - - /* - * How many active statements can we have open at one time to - * this database? Basically, since each Statement downloads - * the results as the query is executed, we can have many. However, - * we can only really have one statement per connection going - * at once (since they are executed serially) - so we return - * one. - * - * @return the maximum - * @exception SQLException if a database access error occurs - */ - public int getMaxStatements() throws SQLException - { - return 1; - } - - /* - * What is the maximum length of a table name - * - * @return max name length in bytes - * @exception SQLException if a database access error occurs - */ - public int getMaxTableNameLength() throws SQLException - { - return getMaxNameLength(); - } - - /* - * What is the maximum number of tables that can be specified - * in a SELECT? - * - * @return the maximum - * @exception SQLException if a database access error occurs - */ - public int getMaxTablesInSelect() throws SQLException - { - return 0; // no limit - } - - /* - * What is the maximum length of a user name - * - * @return the max name length in bytes - * @exception SQLException if a database access error occurs - */ - public int getMaxUserNameLength() throws SQLException - { - return getMaxNameLength(); - } - - - /* - * What is the database's default transaction isolation level? We - * do not support this, so all transactions are SERIALIZABLE. - * - * @return the default isolation level - * @exception SQLException if a database access error occurs - * @see Connection - */ - public int getDefaultTransactionIsolation() throws SQLException - { - return Connection.TRANSACTION_READ_COMMITTED; - } - - /* - * Are transactions supported? If not, commit and rollback are noops - * and the isolation level is TRANSACTION_NONE. We do support - * transactions. - * - * @return true if transactions are supported - * @exception SQLException if a database access error occurs - */ - public boolean supportsTransactions() throws SQLException - { - return true; - } - - /* - * Does the database support the given transaction isolation level? - * We only support TRANSACTION_SERIALIZABLE and TRANSACTION_READ_COMMITTED - * - * @param level the values are defined in java.sql.Connection - * @return true if so - * @exception SQLException if a database access error occurs - * @see Connection - */ - public boolean supportsTransactionIsolationLevel(int level) throws SQLException - { - if (level == Connection.TRANSACTION_SERIALIZABLE || - level == Connection.TRANSACTION_READ_COMMITTED) - return true; - else - return false; - } - - /* - * Are both data definition and data manipulation transactions - * supported? - * - * @return true if so - * @exception SQLException if a database access error occurs - */ - public boolean supportsDataDefinitionAndDataManipulationTransactions() throws SQLException - { - return true; - } - - /* - * Are only data manipulation statements withing a transaction - * supported? - * - * @return true if so - * @exception SQLException if a database access error occurs - */ - public boolean supportsDataManipulationTransactionsOnly() throws SQLException - { - return false; - } - - /* - * Does a data definition statement within a transaction force - * the transaction to commit? I think this means something like: - * - * <p><pre> - * CREATE TABLE T (A INT); - * INSERT INTO T (A) VALUES (2); - * BEGIN; - * UPDATE T SET A = A + 1; - * CREATE TABLE X (A INT); - * SELECT A FROM T INTO X; - * COMMIT; - * </pre><p> - * - * does the CREATE TABLE call cause a commit? The answer is no. - * - * @return true if so - * @exception SQLException if a database access error occurs - */ - public boolean dataDefinitionCausesTransactionCommit() throws SQLException - { - return false; - } - - /* - * Is a data definition statement within a transaction ignored? - * - * @return true if so - * @exception SQLException if a database access error occurs - */ - public boolean dataDefinitionIgnoredInTransactions() throws SQLException - { - return false; - } - - /** - * Escape single quotes with another single quote. - */ - protected static String escapeQuotes(String s) { - StringBuffer sb = new StringBuffer(); - int length = s.length(); - char prevChar = ' '; - char prevPrevChar = ' '; - for (int i=0; i<length; i++) { - char c = s.charAt(i); - sb.append(c); - if (c == '\'' && (prevChar != '\\' || (prevChar == '\\' && prevPrevChar == '\\'))) { - sb.append("'"); - } - prevPrevChar = prevChar; - prevChar = c; - } - return sb.toString(); - } - - /* - * Get a description of stored procedures available in a catalog - * - * <p>Only procedure descriptions matching the schema and procedure - * name criteria are returned. They are ordered by PROCEDURE_SCHEM - * and PROCEDURE_NAME - * - * <p>Each procedure description has the following columns: - * <ol> - * <li><b>PROCEDURE_CAT</b> String => procedure catalog (may be null) - * <li><b>PROCEDURE_SCHEM</b> String => procedure schema (may be null) - * <li><b>PROCEDURE_NAME</b> String => procedure name - * <li><b>Field 4</b> reserved (make it null) - * <li><b>Field 5</b> reserved (make it null) - * <li><b>Field 6</b> reserved (make it null) - * <li><b>REMARKS</b> String => explanatory comment on the procedure - * <li><b>PROCEDURE_TYPE</b> short => kind of procedure - * <ul> - * <li> procedureResultUnknown - May return a result - * <li> procedureNoResult - Does not return a result - * <li> procedureReturnsResult - Returns a result - * </ul> - * </ol> - * - * @param catalog - a catalog name; "" retrieves those without a - * catalog; null means drop catalog name from criteria - * @param schemaParrern - a schema name pattern; "" retrieves those - * without a schema - we ignore this parameter - * @param procedureNamePattern - a procedure name pattern - * @return ResultSet - each row is a procedure description - * @exception SQLException if a database access error occurs - */ - public java.sql.ResultSet getProcedures(String catalog, String schemaPattern, String procedureNamePattern) throws SQLException - { - String sql; - if (connection.haveMinimumServerVersion("7.3")) { - sql = "SELECT NULL AS PROCEDURE_CAT, n.nspname AS PROCEDURE_SCHEM, p.proname AS PROCEDURE_NAME, NULL, NULL, NULL, d.description AS REMARKS, "+java.sql.DatabaseMetaData.procedureReturnsResult+" AS PROCEDURE_TYPE "+ - " FROM pg_catalog.pg_namespace n, pg_catalog.pg_proc p "+ - " LEFT JOIN pg_catalog.pg_description d ON (p.oid=d.objoid) "+ - " LEFT JOIN pg_catalog.pg_class c ON (d.classoid=c.oid AND c.relname='pg_proc') "+ - " LEFT JOIN pg_catalog.pg_namespace pn ON (c.relnamespace=pn.oid AND pn.nspname='pg_catalog') "+ - " WHERE p.pronamespace=n.oid "; - if (schemaPattern != null && !"".equals(schemaPattern)) { - sql += " AND n.nspname LIKE '"+escapeQuotes(schemaPattern)+"' "; - } - if (procedureNamePattern != null) { - sql += " AND p.proname LIKE '"+escapeQuotes(procedureNamePattern)+"' "; - } - sql += " ORDER BY PROCEDURE_SCHEM, PROCEDURE_NAME "; - } else if (connection.haveMinimumServerVersion("7.1")) { - sql = "SELECT NULL AS PROCEDURE_CAT, NULL AS PROCEDURE_SCHEM, p.proname AS PROCEDURE_NAME, NULL, NULL, NULL, d.description AS REMARKS, "+java.sql.DatabaseMetaData.procedureReturnsResult+" AS PROCEDURE_TYPE "+ - " FROM pg_proc p "+ - " LEFT JOIN pg_description d ON (p.oid=d.objoid) "; - if (connection.haveMinimumServerVersion("7.2")) { - sql += " LEFT JOIN pg_class c ON (d.classoid=c.oid AND c.relname='pg_proc') "; - } - if (procedureNamePattern != null) { - sql += " WHERE p.proname LIKE '"+escapeQuotes(procedureNamePattern)+"' "; - } - sql += " ORDER BY PROCEDURE_NAME "; - } else { - sql = "SELECT NULL AS PROCEDURE_CAT, NULL AS PROCEDURE_SCHEM, p.proname AS PROCEDURE_NAME, NULL, NULL, NULL, NULL AS REMARKS, "+java.sql.DatabaseMetaData.procedureReturnsResult+" AS PROCEDURE_TYPE "+ - " FROM pg_proc p "; - if (procedureNamePattern != null) { - sql += " WHERE p.proname LIKE '"+escapeQuotes(procedureNamePattern)+"' "; - } - sql += " ORDER BY PROCEDURE_NAME "; - } - return connection.createStatement().executeQuery(sql); - } - - /* - * Get a description of a catalog's stored procedure parameters - * and result columns. - * - * <p>Only descriptions matching the schema, procedure and parameter - * name criteria are returned. They are ordered by PROCEDURE_SCHEM - * and PROCEDURE_NAME. Within this, the return value, if any, is - * first. Next are the parameter descriptions in call order. The - * column descriptions follow in column number order. - * - * <p>Each row in the ResultSet is a parameter description or column - * description with the following fields: - * <ol> - * <li><b>PROCEDURE_CAT</b> String => procedure catalog (may be null) - * <li><b>PROCEDURE_SCHE</b>M String => procedure schema (may be null) - * <li><b>PROCEDURE_NAME</b> String => procedure name - * <li><b>COLUMN_NAME</b> String => column/parameter name - * <li><b>COLUMN_TYPE</b> Short => kind of column/parameter: - * <ul><li>procedureColumnUnknown - nobody knows - * <li>procedureColumnIn - IN parameter - * <li>procedureColumnInOut - INOUT parameter - * <li>procedureColumnOut - OUT parameter - * <li>procedureColumnReturn - procedure return value - * <li>procedureColumnResult - result column in ResultSet - * </ul> - * <li><b>DATA_TYPE</b> short => SQL type from java.sql.Types - * <li><b>TYPE_NAME</b> String => Data source specific type name - * <li><b>PRECISION</b> int => precision - * <li><b>LENGTH</b> int => length in bytes of data - * <li><b>SCALE</b> short => scale - * <li><b>RADIX</b> short => radix - * <li><b>NULLABLE</b> short => can it contain NULL? - * <ul><li>procedureNoNulls - does not allow NULL values - * <li>procedureNullable - allows NULL values - * <li>procedureNullableUnknown - nullability unknown - * <li><b>REMARKS</b> String => comment describing parameter/column - * </ol> - * @param catalog This is ignored in org.postgresql, advise this is set to null - * @param schemaPattern - * @param procedureNamePattern a procedure name pattern - * @param columnNamePattern a column name pattern, this is currently ignored because postgresql does not name procedure parameters. - * @return each row is a stored procedure parameter or column description - * @exception SQLException if a database-access error occurs - * @see #getSearchStringEscape - */ - // Implementation note: This is required for Borland's JBuilder to work - public java.sql.ResultSet getProcedureColumns(String catalog, String schemaPattern, String procedureNamePattern, String columnNamePattern) throws SQLException - { - Field f[] = new Field[13]; - Vector v = new Vector(); // The new ResultSet tuple stuff - - f[0] = new Field(connection, "PROCEDURE_CAT", iVarcharOid, getMaxNameLength()); - f[1] = new Field(connection, "PROCEDURE_SCHEM", iVarcharOid, getMaxNameLength()); - f[2] = new Field(connection, "PROCEDURE_NAME", iVarcharOid, getMaxNameLength()); - f[3] = new Field(connection, "COLUMN_NAME", iVarcharOid, getMaxNameLength()); - f[4] = new Field(connection, "COLUMN_TYPE", iInt2Oid, 2); - f[5] = new Field(connection, "DATA_TYPE", iInt2Oid, 2); - f[6] = new Field(connection, "TYPE_NAME", iVarcharOid, getMaxNameLength()); - f[7] = new Field(connection, "PRECISION", iInt4Oid, 4); - f[8] = new Field(connection, "LENGTH", iInt4Oid, 4); - f[9] = new Field(connection, "SCALE", iInt2Oid, 2); - f[10] = new Field(connection, "RADIX", iInt2Oid, 2); - f[11] = new Field(connection, "NULLABLE", iInt2Oid, 2); - f[12] = new Field(connection, "REMARKS", iVarcharOid, getMaxNameLength()); - - String sql; - if (connection.haveMinimumServerVersion("7.3")) { - sql = "SELECT n.nspname,p.proname,p.prorettype,p.proargtypes, t.typtype,t.typrelid "+ - " FROM pg_catalog.pg_proc p,pg_catalog.pg_namespace n, pg_catalog.pg_type t "+ - " WHERE p.pronamespace=n.oid AND p.prorettype=t.oid "; - if (schemaPattern != null && !"".equals(schemaPattern)) { - sql += " AND n.nspname LIKE '"+escapeQuotes(schemaPattern)+"' "; - } - if (procedureNamePattern != null) { - sql += " AND p.proname LIKE '"+escapeQuotes(procedureNamePattern)+"' "; - } - sql += " ORDER BY n.nspname, p.proname "; - } else { - sql = "SELECT NULL AS nspname,p.proname,p.prorettype,p.proargtypes, t.typtype,t.typrelid "+ - " FROM pg_proc p,pg_type t "+ - " WHERE p.prorettype=t.oid "; - if (procedureNamePattern != null) { - sql += " AND p.proname LIKE '"+escapeQuotes(procedureNamePattern)+"' "; - } - sql += " ORDER BY p.proname "; - } - - ResultSet rs = connection.createStatement().executeQuery(sql); - while (rs.next()) { - byte schema[] = rs.getBytes("nspname"); - byte procedureName[] = rs.getBytes("proname"); - int returnType = rs.getInt("prorettype"); - String returnTypeType = rs.getString("typtype"); - int returnTypeRelid = rs.getInt("typrelid"); - String strArgTypes = rs.getString("proargtypes"); - StringTokenizer st = new StringTokenizer(strArgTypes); - Vector argTypes = new Vector(); - while (st.hasMoreTokens()) { - argTypes.addElement(new Integer(st.nextToken())); - } - - // decide if we are returning a single column result. - if (!returnTypeType.equals("c")) { - byte[][] tuple = new byte[13][]; - tuple[0] = null; - tuple[1] = schema; - tuple[2] = procedureName; - tuple[3] = encoding.encode("returnValue"); - tuple[4] = encoding.encode(Integer.toString(java.sql.DatabaseMetaData.procedureColumnReturn)); - tuple[5] = encoding.encode(Integer.toString(connection.getSQLType(returnType))); - tuple[6] = encoding.encode(connection.getPGType(returnType)); - tuple[7] = null; - tuple[8] = null; - tuple[9] = null; - tuple[10] = null; - tuple[11] = encoding.encode(Integer.toString(java.sql.DatabaseMetaData.procedureNullableUnknown)); - tuple[12] = null; - v.addElement(tuple); - } - - // Add a row for each argument. - for (int i=0; i<argTypes.size(); i++) { - int argOid = ((Integer)argTypes.elementAt(i)).intValue(); - byte[][] tuple = new byte[13][]; - tuple[0] = null; - tuple[1] = schema; - tuple[2] = procedureName; - tuple[3] = encoding.encode("$"+(i+1)); - tuple[4] = encoding.encode(Integer.toString(java.sql.DatabaseMetaData.procedureColumnIn)); - tuple[5] = encoding.encode(Integer.toString(connection.getSQLType(argOid))); - tuple[6] = encoding.encode(connection.getPGType(argOid)); - tuple[7] = null; - tuple[8] = null; - tuple[9] = null; - tuple[10] = null; - tuple[11] = encoding.encode(Integer.toString(java.sql.DatabaseMetaData.procedureNullableUnknown)); - tuple[12] = null; - v.addElement(tuple); - } - - // if we are returning a multi-column result. - if (returnTypeType.equals("c")) { - String columnsql = "SELECT a.attname,a.atttypid FROM pg_catalog.pg_attribute a WHERE a.attrelid = "+returnTypeRelid+" ORDER BY a.attnum "; - ResultSet columnrs = connection.createStatement().executeQuery(columnsql); - while (columnrs.next()) { - int columnTypeOid = columnrs.getInt("atttypid"); - byte[][] tuple = new byte[13][]; - tuple[0] = null; - tuple[1] = schema; - tuple[2] = procedureName; - tuple[3] = columnrs.getBytes("attname"); - tuple[4] = encoding.encode(Integer.toString(java.sql.DatabaseMetaData.procedureColumnResult)); - tuple[5] = encoding.encode(Integer.toString(connection.getSQLType(columnTypeOid))); - tuple[6] = encoding.encode(connection.getPGType(columnTypeOid)); - tuple[7] = null; - tuple[8] = null; - tuple[9] = null; - tuple[10] = null; - tuple[11] = encoding.encode(Integer.toString(java.sql.DatabaseMetaData.procedureNullableUnknown)); - tuple[12] = null; - v.addElement(tuple); - } - } - } - rs.close(); - - return (ResultSet) ((BaseStatement)connection.createStatement()).createResultSet(f, v, "OK", 1, 0, false); - } - - /* - * Get a description of tables available in a catalog. - * - * <p>Only table descriptions matching the catalog, schema, table - * name and type criteria are returned. They are ordered by - * TABLE_TYPE, TABLE_SCHEM and TABLE_NAME. - * - * <p>Each table description has the following columns: - * - * <ol> - * <li><b>TABLE_CAT</b> String => table catalog (may be null) - * <li><b>TABLE_SCHEM</b> String => table schema (may be null) - * <li><b>TABLE_NAME</b> String => table name - * <li><b>TABLE_TYPE</b> String => table type. Typical types are "TABLE", - * "VIEW", "SYSTEM TABLE", "GLOBAL TEMPORARY", "LOCAL - * TEMPORARY", "ALIAS", "SYNONYM". - * <li><b>REMARKS</b> String => explanatory comment on the table - * </ol> - * - * <p>The valid values for the types parameter are: - * "TABLE", "INDEX", "SEQUENCE", "VIEW", - * "SYSTEM TABLE", "SYSTEM INDEX", "SYSTEM VIEW", - * "SYSTEM TOAST TABLE", "SYSTEM TOAST INDEX", - * "TEMPORARY TABLE", and "TEMPORARY VIEW" - * - * @param catalog a catalog name; For org.postgresql, this is ignored, and - * should be set to null - * @param schemaPattern a schema name pattern - * @param tableNamePattern a table name pattern. For all tables this should be "%" - * @param types a list of table types to include; null returns - * all types - * @return each row is a table description - * @exception SQLException if a database-access error occurs. - */ - public java.sql.ResultSet getTables(String catalog, String schemaPattern, String tableNamePattern, String types[]) throws SQLException - { - String select; - String orderby; - String useSchemas; - if (connection.haveMinimumServerVersion("7.3")) { - useSchemas = "SCHEMAS"; - select = "SELECT NULL AS TABLE_CAT, n.nspname AS TABLE_SCHEM, c.relname AS TABLE_NAME, "+ - " CASE n.nspname LIKE 'pg\\\\_%' OR n.nspname = 'information_schema' "+ - " WHEN true THEN CASE "+ - " WHEN n.nspname = 'pg_catalog' OR n.nspname = 'information_schema' THEN CASE c.relkind "+ - " WHEN 'r' THEN 'SYSTEM TABLE' "+ - " WHEN 'v' THEN 'SYSTEM VIEW' "+ - " WHEN 'i' THEN 'SYSTEM INDEX' "+ - " ELSE NULL "+ - " END "+ - " WHEN n.nspname = 'pg_toast' THEN CASE c.relkind "+ - " WHEN 'r' THEN 'SYSTEM TOAST TABLE' "+ - " WHEN 'i' THEN 'SYSTEM TOAST INDEX' "+ - " ELSE NULL "+ - " END "+ - " ELSE CASE c.relkind "+ - " WHEN 'r' THEN 'TEMPORARY TABLE' "+ - " WHEN 'i' THEN 'TEMPORARY INDEX' "+ - " ELSE NULL "+ - " END "+ - " END "+ - " WHEN false THEN CASE c.relkind "+ - " WHEN 'r' THEN 'TABLE' "+ - " WHEN 'i' THEN 'INDEX' "+ - " WHEN 'S' THEN 'SEQUENCE' "+ - " WHEN 'v' THEN 'VIEW' "+ - " ELSE NULL "+ - " END "+ - " ELSE NULL "+ - " END "+ - " AS TABLE_TYPE, d.description AS REMARKS "+ - " FROM pg_catalog.pg_namespace n, pg_catalog.pg_class c "+ - " LEFT JOIN pg_catalog.pg_description d ON (c.oid = d.objoid AND d.objsubid = 0) "+ - " LEFT JOIN pg_catalog.pg_class dc ON (d.classoid=dc.oid AND dc.relname='pg_class') "+ - " LEFT JOIN pg_catalog.pg_namespace dn ON (dn.oid=dc.relnamespace AND dn.nspname='pg_catalog') "+ - " WHERE c.relnamespace = n.oid "; - if (schemaPattern != null && !"".equals(schemaPattern)) { - select += " AND n.nspname LIKE '"+escapeQuotes(schemaPattern)+"' "; - } - orderby = " ORDER BY TABLE_TYPE,TABLE_SCHEM,TABLE_NAME "; - } else { - useSchemas = "NOSCHEMAS"; - String tableType = ""+ - " CASE c.relname LIKE 'pg\\\\_%' "+ - " WHEN true THEN CASE c.relname LIKE 'pg\\\\_toast\\\\_%' "+ - " WHEN true THEN CASE c.relkind "+ - " WHEN 'r' THEN 'SYSTEM TOAST TABLE' "+ - " WHEN 'i' THEN 'SYSTEM TOAST INDEX' "+ - " ELSE NULL "+ - " END "+ - " WHEN false THEN CASE c.relname LIKE 'pg\\\\_temp\\\\_%' "+ - " WHEN true THEN CASE c.relkind "+ - " WHEN 'r' THEN 'TEMPORARY TABLE' "+ - " WHEN 'i' THEN 'TEMPORARY INDEX' "+ - " ELSE NULL "+ - " END "+ - " WHEN false THEN CASE c.relkind "+ - " WHEN 'r' THEN 'SYSTEM TABLE' "+ - " WHEN 'v' THEN 'SYSTEM VIEW' "+ - " WHEN 'i' THEN 'SYSTEM INDEX' "+ - " ELSE NULL "+ - " END "+ - " ELSE NULL "+ - " END "+ - " ELSE NULL "+ - " END "+ - " WHEN false THEN CASE c.relkind "+ - " WHEN 'r' THEN 'TABLE' "+ - " WHEN 'i' THEN 'INDEX' "+ - " WHEN 'S' THEN 'SEQUENCE' "+ - " WHEN 'v' THEN 'VIEW' "+ - " ELSE NULL "+ - " END "+ - " ELSE NULL "+ - " END "; - orderby = " ORDER BY TABLE_TYPE,TABLE_NAME "; - if (connection.haveMinimumServerVersion("7.2")) { - select = "SELECT NULL AS TABLE_CAT, NULL AS TABLE_SCHEM, c.relname AS TABLE_NAME, "+tableType+" AS TABLE_TYPE, d.description AS REMARKS "+ - " FROM pg_class c "+ - " LEFT JOIN pg_description d ON (c.oid=d.objoid AND d.objsubid = 0) "+ - " LEFT JOIN pg_class dc ON (d.classoid = dc.oid AND dc.relname='pg_class') "+ - " WHERE true "; - } else if (connection.haveMinimumServerVersion("7.1")) { - select = "SELECT NULL AS TABLE_CAT, NULL AS TABLE_SCHEM, c.relname AS TABLE_NAME, "+tableType+" AS TABLE_TYPE, d.description AS REMARKS "+ - " FROM pg_class c "+ - " LEFT JOIN pg_description d ON (c.oid=d.objoid) "+ - " WHERE true "; - } else { - select = "SELECT NULL AS TABLE_CAT, NULL AS TABLE_SCHEM, c.relname AS TABLE_NAME, "+tableType+" AS TABLE_TYPE, NULL AS REMARKS "+ - " FROM pg_class c "+ - " WHERE true "; - } - } - - if (types == null) { - types = defaultTableTypes; - } - if (tableNamePattern != null) { - select += " AND c.relname LIKE '"+escapeQuotes(tableNamePattern)+"' "; - } - String sql = select; - sql += " AND (false "; - for (int i=0; i<types.length; i++) { - Hashtable clauses = (Hashtable)tableTypeClauses.get(types[i]); - if (clauses != null) { - String clause = (String)clauses.get(useSchemas); - sql += " OR ( "+clause+" ) "; - } - } - sql += ") "; - sql += orderby; - - return connection.createStatement().executeQuery(sql); - } - - private static final Hashtable tableTypeClauses; - static { - tableTypeClauses = new Hashtable(); - Hashtable ht = new Hashtable(); - tableTypeClauses.put("TABLE",ht); - ht.put("SCHEMAS","c.relkind = 'r' AND n.nspname NOT LIKE 'pg\\\\_%' AND n.nspname <> 'information_schema'"); - ht.put("NOSCHEMAS","c.relkind = 'r' AND c.relname NOT LIKE 'pg\\\\_%'"); - ht = new Hashtable(); - tableTypeClauses.put("VIEW",ht); - ht.put("SCHEMAS","c.relkind = 'v' AND n.nspname <> 'pg_catalog' AND n.nspname <> 'information_schema'"); - ht.put("NOSCHEMAS","c.relkind = 'v' AND c.relname NOT LIKE 'pg\\\\_%'"); - ht = new Hashtable(); - tableTypeClauses.put("INDEX",ht); - ht.put("SCHEMAS","c.relkind = 'i' AND n.nspname NOT LIKE 'pg\\\\_%' AND n.nspname <> 'information_schema'"); - ht.put("NOSCHEMAS","c.relkind = 'i' AND c.relname NOT LIKE 'pg\\\\_%'"); - ht = new Hashtable(); - tableTypeClauses.put("SEQUENCE",ht); - ht.put("SCHEMAS","c.relkind = 'S'"); - ht.put("NOSCHEMAS","c.relkind = 'S'"); - ht = new Hashtable(); - tableTypeClauses.put("SYSTEM TABLE",ht); - ht.put("SCHEMAS","c.relkind = 'r' AND (n.nspname = 'pg_catalog' OR n.nspname = 'information_schema')"); - ht.put("NOSCHEMAS","c.relkind = 'r' AND c.relname LIKE 'pg\\\\_%' AND c.relname NOT LIKE 'pg\\\\_toast\\\\_%' AND c.relname NOT LIKE 'pg\\\\_temp\\\\_%'"); - ht = new Hashtable(); - tableTypeClauses.put("SYSTEM TOAST TABLE",ht); - ht.put("SCHEMAS","c.relkind = 'r' AND n.nspname = 'pg_toast'"); - ht.put("NOSCHEMAS","c.relkind = 'r' AND c.relname LIKE 'pg\\\\_toast\\\\_%'"); - ht = new Hashtable(); - tableTypeClauses.put("SYSTEM TOAST INDEX",ht); - ht.put("SCHEMAS","c.relkind = 'i' AND n.nspname = 'pg_toast'"); - ht.put("NOSCHEMAS","c.relkind = 'i' AND c.relname LIKE 'pg\\\\_toast\\\\_%'"); - ht = new Hashtable(); - tableTypeClauses.put("SYSTEM VIEW",ht); - ht.put("SCHEMAS","c.relkind = 'v' AND (n.nspname = 'pg_catalog' OR n.nspname = 'information_schema') "); - ht.put("NOSCHEMAS","c.relkind = 'v' AND c.relname LIKE 'pg\\\\_%'"); - ht = new Hashtable(); - tableTypeClauses.put("SYSTEM INDEX",ht); - ht.put("SCHEMAS","c.relkind = 'i' AND (n.nspname = 'pg_catalog' OR n.nspname = 'information_schema') "); - ht.put("NOSCHEMAS","c.relkind = 'v' AND c.relname LIKE 'pg\\\\_%' AND c.relname NOT LIKE 'pg\\\\_toast\\\\_%' AND c.relname NOT LIKE 'pg\\\\_temp\\\\_%'"); - ht = new Hashtable(); - tableTypeClauses.put("TEMPORARY TABLE",ht); - ht.put("SCHEMAS","c.relkind = 'r' AND n.nspname LIKE 'pg\\\\_temp\\\\_%' "); - ht.put("NOSCHEMAS","c.relkind = 'r' AND c.relname LIKE 'pg\\\\_temp\\\\_%' "); - ht = new Hashtable(); - tableTypeClauses.put("TEMPORARY INDEX",ht); - ht.put("SCHEMAS","c.relkind = 'i' AND n.nspname LIKE 'pg\\\\_temp\\\\_%' "); - ht.put("NOSCHEMAS","c.relkind = 'i' AND c.relname LIKE 'pg\\\\_temp\\\\_%' "); - } - - // These are the default tables, used when NULL is passed to getTables - // The choice of these provide the same behaviour as psql's \d - private static final String defaultTableTypes[] = { - "TABLE", "VIEW", "INDEX", "SEQUENCE", "TEMPORARY TABLE" - }; - - /* - * Get the schema names available in this database. The results - * are ordered by schema name. - * - * <P>The schema column is: - * <OL> - * <LI><B>TABLE_SCHEM</B> String => schema name - * </OL> - * - * @return ResultSet each row has a single String column that is a - * schema name - */ - public java.sql.ResultSet getSchemas() throws SQLException - { - String sql; - if (connection.haveMinimumServerVersion("7.3")) { - sql = "SELECT nspname AS TABLE_SCHEM FROM pg_catalog.pg_namespace WHERE nspname <> 'pg_toast' AND nspname NOT LIKE 'pg\\\\_temp\\\\_%' ORDER BY TABLE_SCHEM"; - } else { - sql = "SELECT ''::text AS TABLE_SCHEM ORDER BY TABLE_SCHEM"; - } - return connection.createStatement().executeQuery(sql); - } - - /* - * Get the catalog names available in this database. The results - * are ordered by catalog name. - * - * <P>The catalog column is: - * <OL> - * <LI><B>TABLE_CAT</B> String => catalog name - * </OL> - * - * @return ResultSet each row has a single String column that is a - * catalog name - */ - public java.sql.ResultSet getCatalogs() throws SQLException - { - String sql; - if (connection.haveMinimumServerVersion("7.3")) { - sql = "SELECT datname AS TABLE_CAT FROM pg_catalog.pg_database ORDER BY TABLE_CAT"; - } else { - sql = "SELECT datname AS TABLE_CAT FROM pg_database ORDER BY TABLE_CAT"; - } - return connection.createStatement().executeQuery(sql); - } - - /* - * Get the table types available in this database. The results - * are ordered by table type. - * - * <P>The table type is: - * <OL> - * <LI><B>TABLE_TYPE</B> String => table type. Typical types are "TABLE", - * "VIEW", "SYSTEM TABLE", "GLOBAL TEMPORARY", - * "LOCAL TEMPORARY", "ALIAS", "SYNONYM". - * </OL> - * - * @return ResultSet each row has a single String column that is a - * table type - */ - public java.sql.ResultSet getTableTypes() throws SQLException - { - String types[] = new String[tableTypeClauses.size()]; - Enumeration e = tableTypeClauses.keys(); - int i=0; - while (e.hasMoreElements()) { - types[i++] = (String)e.nextElement();} - sortStringArray(types); - - Field f[] = new Field[1]; - Vector v = new Vector(); - f[0] = new Field(connection, new String("TABLE_TYPE"), iVarcharOid, getMaxNameLength()); - for (i=0; i < types.length; i++) - { - byte[][] tuple = new byte[1][]; - tuple[0] = encoding.encode(types[i]); - v.addElement(tuple); - } - - return (ResultSet) ((BaseStatement)connection.createStatement()).createResultSet(f, v, "OK", 1, 0, false); - } - - /* - * Get a description of table columns available in a catalog. - * - * <P>Only column descriptions matching the catalog, schema, table - * and column name criteria are returned. They are ordered by - * TABLE_SCHEM, TABLE_NAME and ORDINAL_POSITION. - * - * <P>Each column description has the following columns: - * <OL> - * <LI><B>TABLE_CAT</B> String => table catalog (may be null) - * <LI><B>TABLE_SCHEM</B> String => table schema (may be null) - * <LI><B>TABLE_NAME</B> String => table name - * <LI><B>COLUMN_NAME</B> String => column name - * <LI><B>DATA_TYPE</B> short => SQL type from java.sql.Types - * <LI><B>TYPE_NAME</B> String => Data source dependent type name - * <LI><B>COLUMN_SIZE</B> int => column size. For char or date - * types this is the maximum number of characters, for numeric or - * decimal types this is precision. - * <LI><B>BUFFER_LENGTH</B> is not used. - * <LI><B>DECIMAL_DIGITS</B> int => the number of fractional digits - * <LI><B>NUM_PREC_RADIX</B> int => Radix (typically either 10 or 2) - * <LI><B>NULLABLE</B> int => is NULL allowed? - * <UL> - * <LI> columnNoNulls - might not allow NULL values - * <LI> columnNullable - definitely allows NULL values - * <LI> columnNullableUnknown - nullability unknown - * </UL> - * <LI><B>REMARKS</B> String => comment describing column (may be null) - * <LI><B>COLUMN_DEF</B> String => default value (may be null) - * <LI><B>SQL_DATA_TYPE</B> int => unused - * <LI><B>SQL_DATETIME_SUB</B> int => unused - * <LI><B>CHAR_OCTET_LENGTH</B> int => for char types the - * maximum number of bytes in the column - * <LI><B>ORDINAL_POSITION</B> int => index of column in table - * (starting at 1) - * <LI><B>IS_NULLABLE</B> String => "NO" means column definitely - * does not allow NULL values; "YES" means the column might - * allow NULL values. An empty string means nobody knows. - * </OL> - * - * @param catalog a catalog name; "" retrieves those without a catalog - * @param schemaPattern a schema name pattern; "" retrieves those - * without a schema - * @param tableNamePattern a table name pattern - * @param columnNamePattern a column name pattern - * @return ResultSet each row is a column description - * @see #getSearchStringEscape - */ - public java.sql.ResultSet getColumns(String catalog, String schemaPattern, String tableNamePattern, String columnNamePattern) throws SQLException - { - Vector v = new Vector(); // The new ResultSet tuple stuff - Field f[] = new Field[18]; // The field descriptors for the new ResultSet - - f[0] = new Field(connection, "TABLE_CAT", iVarcharOid, getMaxNameLength()); - f[1] = new Field(connection, "TABLE_SCHEM", iVarcharOid, getMaxNameLength()); - f[2] = new Field(connection, "TABLE_NAME", iVarcharOid, getMaxNameLength()); - f[3] = new Field(connection, "COLUMN_NAME", iVarcharOid, getMaxNameLength()); - f[4] = new Field(connection, "DATA_TYPE", iInt2Oid, 2); - f[5] = new Field(connection, "TYPE_NAME", iVarcharOid, getMaxNameLength()); - f[6] = new Field(connection, "COLUMN_SIZE", iInt4Oid, 4); - f[7] = new Field(connection, "BUFFER_LENGTH", iVarcharOid, getMaxNameLength()); - f[8] = new Field(connection, "DECIMAL_DIGITS", iInt4Oid, 4); - f[9] = new Field(connection, "NUM_PREC_RADIX", iInt4Oid, 4); - f[10] = new Field(connection, "NULLABLE", iInt4Oid, 4); - f[11] = new Field(connection, "REMARKS", iVarcharOid, getMaxNameLength()); - f[12] = new Field(connection, "COLUMN_DEF", iVarcharOid, getMaxNameLength()); - f[13] = new Field(connection, "SQL_DATA_TYPE", iInt4Oid, 4); - f[14] = new Field(connection, "SQL_DATETIME_SUB", iInt4Oid, 4); - f[15] = new Field(connection, "CHAR_OCTET_LENGTH", iVarcharOid, getMaxNameLength()); - f[16] = new Field(connection, "ORDINAL_POSITION", iInt4Oid, 4); - f[17] = new Field(connection, "IS_NULLABLE", iVarcharOid, getMaxNameLength()); - - String sql; - if (connection.haveMinimumServerVersion("7.3")) { - sql = "SELECT n.nspname,c.relname,a.attname,a.atttypid,a.attnotnull,a.atttypmod,a.attlen,a.attnum,def.adsrc,dsc.description "+ - " FROM pg_catalog.pg_namespace n "+ - " JOIN pg_catalog.pg_class c ON (c.relnamespace = n.oid) "+ - " JOIN pg_catalog.pg_attribute a ON (a.attrelid=c.oid) "+ - " LEFT JOIN pg_catalog.pg_attrdef def ON (a.attrelid=def.adrelid AND a.attnum = def.adnum) "+ - " LEFT JOIN pg_catalog.pg_description dsc ON (c.oid=dsc.objoid AND a.attnum = dsc.objsubid) "+ - " LEFT JOIN pg_catalog.pg_class dc ON (dc.oid=dsc.classoid AND dc.relname='pg_class') "+ - " LEFT JOIN pg_catalog.pg_namespace dn ON (dc.relnamespace=dn.oid AND dn.nspname='pg_catalog') "+ - " WHERE a.attnum > 0 AND NOT a.attisdropped "; - if (schemaPattern != null && !"".equals(schemaPattern)) { - sql += " AND n.nspname LIKE '"+escapeQuotes(schemaPattern)+"' "; - } - } else if (connection.haveMinimumServerVersion("7.2")) { - sql = "SELECT NULL::text AS nspname,c.relname,a.attname,a.atttypid,a.attnotnull,a.atttypmod,a.attlen,a.attnum,def.adsrc,dsc.description "+ - " FROM pg_class c "+ - " JOIN pg_attribute a ON (a.attrelid=c.oid) "+ - " LEFT JOIN pg_attrdef def ON (a.attrelid=def.adrelid AND a.attnum = def.adnum) "+ - " LEFT JOIN pg_description dsc ON (c.oid=dsc.objoid AND a.attnum = dsc.objsubid) "+ - " LEFT JOIN pg_class dc ON (dc.oid=dsc.classoid AND dc.relname='pg_class') "+ - " WHERE a.attnum > 0 "; - } else if (connection.haveMinimumServerVersion("7.1")) { - sql = "SELECT NULL::text AS nspname,c.relname,a.attname,a.atttypid,a.attnotnull,a.atttypmod,a.attlen,a.attnum,def.adsrc,dsc.description "+ - " FROM pg_class c "+ - " JOIN pg_attribute a ON (a.attrelid=c.oid) "+ - " LEFT JOIN pg_attrdef def ON (a.attrelid=def.adrelid AND a.attnum = def.adnum) "+ - " LEFT JOIN pg_description dsc ON (a.oid=dsc.objoid) "+ - " WHERE a.attnum > 0 "; - } else { - // if < 7.1 then don't get defaults or descriptions. - sql = "SELECT NULL::text AS nspname,c.relname,a.attname,a.atttypid,a.attnotnull,a.atttypmod,a.attlen,a.attnum,NULL AS adsrc,NULL AS description "+ - " FROM pg_class c, pg_attribute a "+ - " WHERE a.attrelid=c.oid AND a.attnum > 0 "; - } - - if (tableNamePattern != null && !"".equals(tableNamePattern)) { - sql += " AND c.relname LIKE '"+escapeQuotes(tableNamePattern)+"' "; - } - if (columnNamePattern != null && !"".equals(columnNamePattern)) { - sql += " AND a.attname LIKE '"+escapeQuotes(columnNamePattern)+"' "; - } - sql += " ORDER BY nspname,relname,attnum "; - - ResultSet rs = connection.createStatement().executeQuery(sql); - while (rs.next()) - { - byte[][] tuple = new byte[18][]; - int typeOid = rs.getInt("atttypid"); - - tuple[0] = null; // Catalog name, not supported - tuple[1] = rs.getBytes("nspname"); // Schema - tuple[2] = rs.getBytes("relname"); // Table name - tuple[3] = rs.getBytes("attname"); // Column name - tuple[4] = encoding.encode(Integer.toString(connection.getSQLType(typeOid))); - String pgType = connection.getPGType(typeOid); - tuple[5] = encoding.encode(pgType); // Type name - - // by default no decimal_digits - // if the type is numeric or decimal we will - // overwrite later. - tuple[8] = encoding.encode("0"); - - if (pgType.equals("bpchar") || pgType.equals("varchar")) - { - int atttypmod = rs.getInt("atttypmod"); - tuple[6] = encoding.encode(Integer.toString(atttypmod != -1 ? atttypmod - VARHDRSZ : 0)); - } - else if (pgType.equals("numeric") || pgType.equals("decimal")) - { - int attypmod = rs.getInt("atttypmod") - VARHDRSZ; - tuple[6] = encoding.encode(Integer.toString( ( attypmod >> 16 ) & 0xffff )); - tuple[8] = encoding.encode(Integer.toString(attypmod & 0xffff)); - tuple[9] = encoding.encode("10"); - } - else if (pgType.equals("bit") || pgType.equals("varbit")) { - tuple[6] = rs.getBytes("atttypmod"); - tuple[9] = encoding.encode("2"); - } - else { - tuple[6] = rs.getBytes("attlen"); - tuple[9] = encoding.encode("10"); - } - - tuple[7] = null; // Buffer length - - tuple[10] = encoding.encode(Integer.toString(rs.getBoolean("attnotnull") ? java.sql.DatabaseMetaData.columnNoNulls : java.sql.DatabaseMetaData.columnNullable)); // Nullable - tuple[11] = rs.getBytes("description"); // Description (if any) - tuple[12] = rs.getBytes("adsrc"); // Column default - tuple[13] = null; // sql data type (unused) - tuple[14] = null; // sql datetime sub (unused) - tuple[15] = tuple[6]; // char octet length - tuple[16] = rs.getBytes("attnum"); // ordinal position - tuple[17] = encoding.encode(rs.getBoolean("attnotnull") ? "NO" : "YES"); // Is nullable - - v.addElement(tuple); - } - rs.close(); - - return (ResultSet) ((BaseStatement)connection.createStatement()).createResultSet(f, v, "OK", 1, 0, false); - } - - /* - * Get a description of the access rights for a table's columns. - * - * <P>Only privileges matching the column name criteria are - * returned. They are ordered by COLUMN_NAME and PRIVILEGE. - * - * <P>Each privilige description has the following columns: - * <OL> - * <LI><B>TABLE_CAT</B> String => table catalog (may be null) - * <LI><B>TABLE_SCHEM</B> String => table schema (may be null) - * <LI><B>TABLE_NAME</B> String => table name - * <LI><B>COLUMN_NAME</B> String => column name - * <LI><B>GRANTOR</B> => grantor of access (may be null) - * <LI><B>GRANTEE</B> String => grantee of access - * <LI><B>PRIVILEGE</B> String => name of access (SELECT, - * INSERT, UPDATE, REFRENCES, ...) - * <LI><B>IS_GRANTABLE</B> String => "YES" if grantee is permitted - * to grant to others; "NO" if not; null if unknown - * </OL> - * - * @param catalog a catalog name; "" retrieves those without a catalog - * @param schema a schema name; "" retrieves those without a schema - * @param table a table name - * @param columnNamePattern a column name pattern - * @return ResultSet each row is a column privilege description - * @see #getSearchStringEscape - */ - public java.sql.ResultSet getColumnPrivileges(String catalog, String schema, String table, String columnNamePattern) throws SQLException - { - Field f[] = new Field[8]; - Vector v = new Vector(); - - if (table == null) - table = "%"; - - if (columnNamePattern == null) - columnNamePattern = "%"; - - f[0] = new Field(connection, "TABLE_CAT", iVarcharOid, getMaxNameLength()); - f[1] = new Field(connection, "TABLE_SCHEM", iVarcharOid, getMaxNameLength()); - f[2] = new Field(connection, "TABLE_NAME", iVarcharOid, getMaxNameLength()); - f[3] = new Field(connection, "COLUMN_NAME", iVarcharOid, getMaxNameLength()); - f[4] = new Field(connection, "GRANTOR", iVarcharOid, getMaxNameLength()); - f[5] = new Field(connection, "GRANTEE", iVarcharOid, getMaxNameLength()); - f[6] = new Field(connection, "PRIVILEGE", iVarcharOid, getMaxNameLength()); - f[7] = new Field(connection, "IS_GRANTABLE", iVarcharOid, getMaxNameLength()); - - String sql; - if (connection.haveMinimumServerVersion("7.3")) { - sql = "SELECT n.nspname,c.relname,u.usename,c.relacl,a.attname "+ - " FROM pg_catalog.pg_namespace n, pg_catalog.pg_class c, pg_catalog.pg_user u, pg_catalog.pg_attribute a "+ - " WHERE c.relnamespace = n.oid "+ - " AND u.usesysid = c.relowner "+ - " AND c.oid = a.attrelid "+ - " AND c.relkind = 'r' "+ - " AND a.attnum > 0 AND NOT a.attisdropped "; - if (schema != null && !"".equals(schema)) { - sql += " AND n.nspname = '"+escapeQuotes(schema)+"' "; - } - } else { - sql = "SELECT NULL::text AS nspname,c.relname,u.usename,c.relacl,a.attname "+ - "FROM pg_class c, pg_user u,pg_attribute a "+ - " WHERE u.usesysid = c.relowner "+ - " AND c.oid = a.attrelid "+ - " AND a.attnum > 0 "+ - " AND c.relkind = 'r' "; - } - - sql += " AND c.relname = '"+escapeQuotes(table)+"' "; - if (columnNamePattern != null && !"".equals(columnNamePattern)) { - sql += " AND a.attname LIKE '"+escapeQuotes(columnNamePattern)+"' "; - } - sql += " ORDER BY attname "; - - ResultSet rs = connection.createStatement().executeQuery(sql); - while (rs.next()) { - byte schemaName[] = rs.getBytes("nspname"); - byte tableName[] = rs.getBytes("relname"); - byte column[] = rs.getBytes("attname"); - String owner = rs.getString("usename"); - String acl = rs.getString("relacl"); - Hashtable permissions = parseACL(acl, owner); - String permNames[] = new String[permissions.size()]; - Enumeration e = permissions.keys(); - int i=0; - while (e.hasMoreElements()) { - permNames[i++] = (String)e.nextElement(); - } - sortStringArray(permNames); - for (i=0; i<permNames.length; i++) { - byte[] privilege = encoding.encode(permNames[i]); - Vector grantees = (Vector)permissions.get(permNames[i]); - for (int j=0; j<grantees.size(); j++) { - String grantee = (String)grantees.elementAt(j); - String grantable = owner.equals(grantee) ? "YES" : "NO"; - byte[][] tuple = new byte[8][]; - tuple[0] = null; - tuple[1] = schemaName; - tuple[2] = tableName; - tuple[3] = column; - tuple[4] = encoding.encode(owner); - tuple[5] = encoding.encode(grantee); - tuple[6] = privilege; - tuple[7] = encoding.encode(grantable); - v.addElement(tuple); - } - } - } - rs.close(); - - return (ResultSet) ((BaseStatement)connection.createStatement()).createResultSet(f, v, "OK", 1, 0, false); - } - - /* - * Get a description of the access rights for each table available - * in a catalog. - * - * This method is currently unimplemented. - * - * <P>Only privileges matching the schema and table name - * criteria are returned. They are ordered by TABLE_SCHEM, - * TABLE_NAME, and PRIVILEGE. - * - * <P>Each privilige description has the following columns: - * <OL> - * <LI><B>TABLE_CAT</B> String => table catalog (may be null) - * <LI><B>TABLE_SCHEM</B> String => table schema (may be null) - * <LI><B>TABLE_NAME</B> String => table name - * <LI><B>GRANTOR</B> => grantor of access (may be null) - * <LI><B>GRANTEE</B> String => grantee of access - * <LI><B>PRIVILEGE</B> String => name of access (SELECT, - * INSERT, UPDATE, REFRENCES, ...) - * <LI><B>IS_GRANTABLE</B> String => "YES" if grantee is permitted - * to grant to others; "NO" if not; null if unknown - * </OL> - * - * @param catalog a catalog name; "" retrieves those without a catalog - * @param schemaPattern a schema name pattern; "" retrieves those - * without a schema - * @param tableNamePattern a table name pattern - * @return ResultSet each row is a table privilege description - * @see #getSearchStringEscape - */ - public java.sql.ResultSet getTablePrivileges(String catalog, String schemaPattern, String tableNamePattern) throws SQLException - { - Field f[] = new Field[7]; - Vector v = new Vector(); - - f[0] = new Field(connection, "TABLE_CAT", iVarcharOid, getMaxNameLength()); - f[1] = new Field(connection, "TABLE_SCHEM", iVarcharOid, getMaxNameLength()); - f[2] = new Field(connection, "TABLE_NAME", iVarcharOid, getMaxNameLength()); - f[3] = new Field(connection, "GRANTOR", iVarcharOid, getMaxNameLength()); - f[4] = new Field(connection, "GRANTEE", iVarcharOid, getMaxNameLength()); - f[5] = new Field(connection, "PRIVILEGE", iVarcharOid, getMaxNameLength()); - f[6] = new Field(connection, "IS_GRANTABLE", iVarcharOid, getMaxNameLength()); - - String sql; - if (connection.haveMinimumServerVersion("7.3")) { - sql = "SELECT n.nspname,c.relname,u.usename,c.relacl "+ - " FROM pg_catalog.pg_namespace n, pg_catalog.pg_class c, pg_catalog.pg_user u "+ - " WHERE c.relnamespace = n.oid "+ - " AND u.usesysid = c.relowner "+ - " AND c.relkind = 'r' "; - if (schemaPattern != null && !"".equals(schemaPattern)) { - sql += " AND n.nspname LIKE '"+escapeQuotes(schemaPattern)+"' "; - } - } else { - sql = "SELECT NULL::text AS nspname,c.relname,u.usename,c.relacl "+ - "FROM pg_class c, pg_user u "+ - " WHERE u.usesysid = c.relowner "+ - " AND c.relkind = 'r' "; - } - - if (tableNamePattern != null && !"".equals(tableNamePattern)) { - sql += " AND c.relname LIKE '"+escapeQuotes(tableNamePattern)+"' "; - } - sql += " ORDER BY nspname, relname "; - - ResultSet rs = connection.createStatement().executeQuery(sql); - while (rs.next()) { - byte schema[] = rs.getBytes("nspname"); - byte table[] = rs.getBytes("relname"); - String owner = rs.getString("usename"); - String acl = rs.getString("relacl"); - Hashtable permissions = parseACL(acl, owner); - String permNames[] = new String[permissions.size()]; - Enumeration e = permissions.keys(); - int i=0; - while (e.hasMoreElements()) { - permNames[i++] = (String)e.nextElement(); - } - sortStringArray(permNames); - for (i=0; i<permNames.length; i++) { - byte[] privilege = encoding.encode(permNames[i]); - Vector grantees = (Vector)permissions.get(permNames[i]); - for (int j=0; j<grantees.size(); j++) { - String grantee = (String)grantees.elementAt(j); - String grantable = owner.equals(grantee) ? "YES" : "NO"; - byte[][] tuple = new byte[7][]; - tuple[0] = null; - tuple[1] = schema; - tuple[2] = table; - tuple[3] = encoding.encode(owner); - tuple[4] = encoding.encode(grantee); - tuple[5] = privilege; - tuple[6] = encoding.encode(grantable); - v.addElement(tuple); - } - } - } - rs.close(); - - return (ResultSet) ((BaseStatement)connection.createStatement()).createResultSet(f, v, "OK", 1, 0, false); - } - - private static void sortStringArray(String s[]) { - for (int i=0; i<s.length-1; i++) { - for (int j=i+1; j<s.length; j++) { - if (s[i].compareTo(s[j]) > 0) { - String tmp = s[i]; - s[i] = s[j]; - s[j] = tmp; - } - } - } - } - - /** - * Parse an String of ACLs into a Vector of ACLs. - */ - private static Vector parseACLArray(String aclString) { - Vector acls = new Vector(); - if (aclString == null || aclString.length() == 0) { - return acls; - } - boolean inQuotes = false; - // start at 1 because of leading "{" - int beginIndex = 1; - char prevChar = ' '; - for (int i=beginIndex; i<aclString.length(); i++) { - - char c = aclString.charAt(i); - if (c == '"' && prevChar != '\\') { - inQuotes = !inQuotes; - } else if (c == ',' && !inQuotes) { - acls.addElement(aclString.substring(beginIndex,i)); - beginIndex = i+1; - } - prevChar = c; - } - // add last element removing the trailing "}" - acls.addElement(aclString.substring(beginIndex,aclString.length()-1)); - - // Strip out enclosing quotes, if any. - for (int i=0; i<acls.size(); i++) { - String acl = (String)acls.elementAt(i); - if (acl.startsWith("\"") && acl.endsWith("\"")) { - acl = acl.substring(1,acl.length()-1); - acls.setElementAt(acl,i); - } - } - return acls; - } - - /** - * Add the user described by the given acl to the Vectors of users - * with the privileges described by the acl. - */ - private void addACLPrivileges(String acl, Hashtable privileges) { - int equalIndex = acl.lastIndexOf("="); - String name = acl.substring(0,equalIndex); - if (name.length() == 0) { - name = "PUBLIC"; - } - String privs = acl.substring(equalIndex+1); - for (int i=0; i<privs.length(); i++) { - char c = privs.charAt(i); - String sqlpriv; - switch (c) { - case 'a': sqlpriv = "INSERT"; break; - case 'r': sqlpriv = "SELECT"; break; - case 'w': sqlpriv = "UPDATE"; break; - case 'd': sqlpriv = "DELETE"; break; - case 'R': sqlpriv = "RULE"; break; - case 'x': sqlpriv = "REFERENCES"; break; - case 't': sqlpriv = "TRIGGER"; break; - // the folloowing can't be granted to a table, but - // we'll keep them for completeness. - case 'X': sqlpriv = "EXECUTE"; break; - case 'U': sqlpriv = "USAGE"; break; - case 'C': sqlpriv = "CREATE"; break; - case 'T': sqlpriv = "CREATE TEMP"; break; - default: sqlpriv = "UNKNOWN"; - } - Vector usersWithPermission = (Vector)privileges.get(sqlpriv); - if (usersWithPermission == null) { - usersWithPermission = new Vector(); - privileges.put(sqlpriv,usersWithPermission); - } - usersWithPermission.addElement(name); - } - } - - /** - * Take the a String representing an array of ACLs and return - * a Hashtable mapping the SQL permission name to a Vector of - * usernames who have that permission. - */ - protected Hashtable parseACL(String aclArray, String owner) { - if (aclArray == null || aclArray == "") { - //null acl is a shortcut for owner having full privs - aclArray = "{" + owner + "=arwdRxt}"; - } - Vector acls = parseACLArray(aclArray); - Hashtable privileges = new Hashtable(); - for (int i=0; i<acls.size(); i++) { - String acl = (String)acls.elementAt(i); - addACLPrivileges(acl,privileges); - } - return privileges; - } - - /* - * Get a description of a table's optimal set of columns that - * uniquely identifies a row. They are ordered by SCOPE. - * - * <P>Each column description has the following columns: - * <OL> - * <LI><B>SCOPE</B> short => actual scope of result - * <UL> - * <LI> bestRowTemporary - very temporary, while using row - * <LI> bestRowTransaction - valid for remainder of current transaction - * <LI> bestRowSession - valid for remainder of current session - * </UL> - * <LI><B>COLUMN_NAME</B> String => column name - * <LI><B>DATA_TYPE</B> short => SQL data type from java.sql.Types - * <LI><B>TYPE_NAME</B> String => Data source dependent type name - * <LI><B>COLUMN_SIZE</B> int => precision - * <LI><B>BUFFER_LENGTH</B> int => not used - * <LI><B>DECIMAL_DIGITS</B> short => scale - * <LI><B>PSEUDO_COLUMN</B> short => is this a pseudo column - * like an Oracle ROWID - * <UL> - * <LI> bestRowUnknown - may or may not be pseudo column - * <LI> bestRowNotPseudo - is NOT a pseudo column - * <LI> bestRowPseudo - is a pseudo column - * </UL> - * </OL> - * - * @param catalog a catalog name; "" retrieves those without a catalog - * @param schema a schema name; "" retrieves those without a schema - * @param table a table name - * @param scope the scope of interest; use same values as SCOPE - * @param nullable include columns that are nullable? - * @return ResultSet each row is a column description - */ - // Implementation note: This is required for Borland's JBuilder to work - public java.sql.ResultSet getBestRowIdentifier(String catalog, String schema, String table, int scope, boolean nullable) throws SQLException - { - Field f[] = new Field[8]; - Vector v = new Vector(); // The new ResultSet tuple stuff - - f[0] = new Field(connection, "SCOPE", iInt2Oid, 2); - f[1] = new Field(connection, "COLUMN_NAME", iVarcharOid, getMaxNameLength()); - f[2] = new Field(connection, "DATA_TYPE", iInt2Oid, 2); - f[3] = new Field(connection, "TYPE_NAME", iVarcharOid, getMaxNameLength()); - f[4] = new Field(connection, "COLUMN_SIZE", iInt4Oid, 4); - f[5] = new Field(connection, "BUFFER_LENGTH", iInt4Oid, 4); - f[6] = new Field(connection, "DECIMAL_DIGITS", iInt2Oid, 2); - f[7] = new Field(connection, "PSEUDO_COLUMN", iInt2Oid, 2); - - /* At the moment this simply returns a table's primary key, - * if there is one. I believe other unique indexes, ctid, - * and oid should also be considered. -KJ - */ - - String from; - String where = ""; - if (connection.haveMinimumServerVersion("7.3")) { - from = " FROM pg_catalog.pg_namespace n, pg_catalog.pg_class ct, pg_catalog.pg_class ci, pg_catalog.pg_attribute a, pg_catalog.pg_index i "; - where = " AND ct.relnamespace = n.oid "; - if (schema != null && !"".equals(schema)) { - where += " AND n.nspname = '"+escapeQuotes(schema)+"' "; - } - } else { - from = " FROM pg_class ct, pg_class ci, pg_attribute a, pg_index i "; - } - String sql = "SELECT a.attname, a.atttypid "+ - from+ - " WHERE ct.oid=i.indrelid AND ci.oid=i.indexrelid "+ - " AND a.attrelid=ci.oid AND i.indisprimary "+ - " AND ct.relname = '"+escapeQuotes(table)+"' "+ - where+ - " ORDER BY a.attnum "; - - ResultSet rs = connection.createStatement().executeQuery(sql); - while (rs.next()) { - byte tuple[][] = new byte[8][]; - int columnTypeOid = rs.getInt("atttypid"); - tuple[0] = encoding.encode(Integer.toString(scope)); - tuple[1] = rs.getBytes("attname"); - tuple[2] = encoding.encode(Integer.toString(connection.getSQLType(columnTypeOid))); - tuple[3] = encoding.encode(connection.getPGType(columnTypeOid)); - tuple[4] = null; - tuple[5] = null; - tuple[6] = null; - tuple[7] = encoding.encode(Integer.toString(java.sql.DatabaseMetaData.bestRowNotPseudo)); - v.addElement(tuple); - } - - return (ResultSet) ((BaseStatement)connection.createStatement()).createResultSet(f, v, "OK", 1, 0, false); - } - - /* - * Get a description of a table's columns that are automatically - * updated when any value in a row is updated. They are - * unordered. - * - * <P>Each column description has the following columns: - * <OL> - * <LI><B>SCOPE</B> short => is not used - * <LI><B>COLUMN_NAME</B> String => column name - * <LI><B>DATA_TYPE</B> short => SQL data type from java.sql.Types - * <LI><B>TYPE_NAME</B> String => Data source dependent type name - * <LI><B>COLUMN_SIZE</B> int => precision - * <LI><B>BUFFER_LENGTH</B> int => length of column value in bytes - * <LI><B>DECIMAL_DIGITS</B> short => scale - * <LI><B>PSEUDO_COLUMN</B> short => is this a pseudo column - * like an Oracle ROWID - * <UL> - * <LI> versionColumnUnknown - may or may not be pseudo column - * <LI> versionColumnNotPseudo - is NOT a pseudo column - * <LI> versionColumnPseudo - is a pseudo column - * </UL> - * </OL> - * - * @param catalog a catalog name; "" retrieves those without a catalog - * @param schema a schema name; "" retrieves those without a schema - * @param table a table name - * @return ResultSet each row is a column description - */ - public java.sql.ResultSet getVersionColumns(String catalog, String schema, String table) throws SQLException - { - Field f[] = new Field[8]; - Vector v = new Vector(); // The new ResultSet tuple stuff - - f[0] = new Field(connection, "SCOPE", iInt2Oid, 2); - f[1] = new Field(connection, "COLUMN_NAME", iVarcharOid, getMaxNameLength()); - f[2] = new Field(connection, "DATA_TYPE", iInt2Oid, 2); - f[3] = new Field(connection, "TYPE_NAME", iVarcharOid, getMaxNameLength()); - f[4] = new Field(connection, "COLUMN_SIZE", iInt4Oid, 4); - f[5] = new Field(connection, "BUFFER_LENGTH", iInt4Oid, 4); - f[6] = new Field(connection, "DECIMAL_DIGITS", iInt2Oid, 2); - f[7] = new Field(connection, "PSEUDO_COLUMN", iInt2Oid, 2); - - byte tuple[][] = new byte[8][]; - - /* Postgresql does not have any column types that are - * automatically updated like some databases' timestamp type. - * We can't tell what rules or triggers might be doing, so we - * are left with the system columns that change on an update. - * An update may change all of the following system columns: - * ctid, xmax, xmin, cmax, and cmin. Depending on if we are - * in a transaction and wether we roll it back or not the - * only guaranteed change is to ctid. -KJ - */ - - tuple[0] = null; - tuple[1] = encoding.encode("ctid"); - tuple[2] = encoding.encode(Integer.toString(connection.getSQLType("tid"))); - tuple[3] = encoding.encode("tid"); - tuple[4] = null; - tuple[5] = null; - tuple[6] = null; - tuple[7] = encoding.encode(Integer.toString(java.sql.DatabaseMetaData.versionColumnPseudo)); - v.addElement(tuple); - - /* Perhaps we should check that the given - * catalog.schema.table actually exists. -KJ - */ - return (ResultSet) ((BaseStatement)connection.createStatement()).createResultSet(f, v, "OK", 1, 0, false); - } - - /* - * Get a description of a table's primary key columns. They - * are ordered by COLUMN_NAME. - * - * <P>Each column description has the following columns: - * <OL> - * <LI><B>TABLE_CAT</B> String => table catalog (may be null) - * <LI><B>TABLE_SCHEM</B> String => table schema (may be null) - * <LI><B>TABLE_NAME</B> String => table name - * <LI><B>COLUMN_NAME</B> String => column name - * <LI><B>KEY_SEQ</B> short => sequence number within primary key - * <LI><B>PK_NAME</B> String => primary key name (may be null) - * </OL> - * - * @param catalog a catalog name; "" retrieves those without a catalog - * @param schema a schema name pattern; "" retrieves those - * without a schema - * @param table a table name - * @return ResultSet each row is a primary key column description - */ - public java.sql.ResultSet getPrimaryKeys(String catalog, String schema, String table) throws SQLException - { - String select; - String from; - String where = ""; - if (connection.haveMinimumServerVersion("7.3")) { - select = "SELECT NULL AS TABLE_CAT, n.nspname AS TABLE_SCHEM, "; - from = " FROM pg_catalog.pg_namespace n, pg_catalog.pg_class ct, pg_catalog.pg_class ci, pg_catalog.pg_attribute a, pg_catalog.pg_index i "; - where = " AND ct.relnamespace = n.oid "; - if (schema != null && !"".equals(schema)) { - where += " AND n.nspname = '"+escapeQuotes(schema)+"' "; - } - } else { - select = "SELECT NULL AS TABLE_CAT, NULL AS TABLE_SCHEM, "; - from = " FROM pg_class ct, pg_class ci, pg_attribute a, pg_index i "; - } - String sql = select+ - " ct.relname AS TABLE_NAME, "+ - " a.attname AS COLUMN_NAME, "+ - " a.attnum AS KEY_SEQ, "+ - " ci.relname AS PK_NAME "+ - from+ - " WHERE ct.oid=i.indrelid AND ci.oid=i.indexrelid "+ - " AND a.attrelid=ci.oid AND i.indisprimary "; - if (table != null && !"".equals(table)) { - sql += " AND ct.relname = '"+escapeQuotes(table)+"' "; - } - sql += where+ - " ORDER BY table_name, pk_name, key_seq"; - return connection.createStatement().executeQuery(sql); - } - - /** - * - * @param catalog - * @param schema - * @param primaryTable if provided will get the keys exported by this table - * @param foreignTable if provided will get the keys imported by this table - * @return ResultSet - * @throws SQLException - */ - - protected java.sql.ResultSet getImportedExportedKeys(String primaryCatalog, String primarySchema, String primaryTable, String foreignCatalog, String foreignSchema, String foreignTable) throws SQLException - { - Field f[] = new Field[14]; - - f[0] = new Field(connection, "PKTABLE_CAT", iVarcharOid, getMaxNameLength()); - f[1] = new Field(connection, "PKTABLE_SCHEM", iVarcharOid, getMaxNameLength()); - f[2] = new Field(connection, "PKTABLE_NAME", iVarcharOid, getMaxNameLength()); - f[3] = new Field(connection, "PKCOLUMN_NAME", iVarcharOid, getMaxNameLength()); - f[4] = new Field(connection, "FKTABLE_CAT", iVarcharOid, getMaxNameLength()); - f[5] = new Field(connection, "FKTABLE_SCHEM", iVarcharOid, getMaxNameLength()); - f[6] = new Field(connection, "FKTABLE_NAME", iVarcharOid, getMaxNameLength()); - f[7] = new Field(connection, "FKCOLUMN_NAME", iVarcharOid, getMaxNameLength()); - f[8] = new Field(connection, "KEY_SEQ", iInt2Oid, 2); - f[9] = new Field(connection, "UPDATE_RULE", iInt2Oid, 2); - f[10] = new Field(connection, "DELETE_RULE", iInt2Oid, 2); - f[11] = new Field(connection, "FK_NAME", iVarcharOid, getMaxNameLength()); - f[12] = new Field(connection, "PK_NAME", iVarcharOid, getMaxNameLength()); - f[13] = new Field(connection, "DEFERRABILITY", iInt2Oid, 2); - - - String select; - String from; - String where = ""; - - /* - * The addition of the pg_constraint in 7.3 table should have really - * helped us out here, but it comes up just a bit short. - * - The conkey, confkey columns aren't really useful without - * contrib/array unless we want to issues separate queries. - * - Unique indexes that can support foreign keys are not necessarily - * added to pg_constraint. Also multiple unique indexes covering - * the same keys can be created which make it difficult to determine - * the PK_NAME field. - */ - - if (connection.haveMinimumServerVersion("7.4")) { - String sql = "SELECT NULL::text AS PKTABLE_CAT, pkn.nspname AS PKTABLE_SCHEMA, pkc.relname AS PKTABLE_NAME, pka.attname AS PKCOLUMN_NAME, "+ - "NULL::text AS FK_TABLE_CAT, fkn.nspname AS FKTABLE_SCHEMA, fkc.relname AS FKTABLE_NAME, fka.attname AS FKCOLUMN_NAME, "+ - "pos.n AS KEY_SEQ, "+ - "CASE con.confupdtype "+ - " WHEN 'c' THEN " + DatabaseMetaData.importedKeyCascade + - " WHEN 'n' THEN " + DatabaseMetaData.importedKeySetNull + - " WHEN 'd' THEN " + DatabaseMetaData.importedKeySetDefault + - " WHEN 'r' THEN " + DatabaseMetaData.importedKeyRestrict + - " WHEN 'a' THEN " + DatabaseMetaData.importedKeyNoAction + - " ELSE NULL END AS UPDATE_RULE, "+ - "CASE con.confdeltype "+ - " WHEN 'c' THEN " + DatabaseMetaData.importedKeyCascade + - " WHEN 'n' THEN " + DatabaseMetaData.importedKeySetNull + - " WHEN 'd' THEN " + DatabaseMetaData.importedKeySetDefault + - " WHEN 'r' THEN " + DatabaseMetaData.importedKeyRestrict + - " WHEN 'a' THEN " + DatabaseMetaData.importedKeyNoAction + - " ELSE NULL END AS DELETE_RULE, "+ - "con.conname AS FK_NAME, pkic.relname AS PK_NAME, "+ - "CASE "+ - " WHEN con.condeferrable AND con.condeferred THEN " + DatabaseMetaData.importedKeyInitiallyDeferred + - " WHEN con.condeferrable THEN " + DatabaseMetaData.importedKeyInitiallyImmediate + - " ELSE " + DatabaseMetaData.importedKeyNotDeferrable+ - " END AS DEFERRABILITY "+ - " FROM "+ - " pg_catalog.pg_namespace pkn, pg_catalog.pg_class pkc, pg_catalog.pg_attribute pka, "+ - " pg_catalog.pg_namespace fkn, pg_catalog.pg_class fkc, pg_catalog.pg_attribute fka, "+ - " pg_catalog.pg_constraint con, information_schema._pg_keypositions() pos(n), "+ - " pg_catalog.pg_depend dep, pg_catalog.pg_class pkic "+ - " WHERE pkn.oid = pkc.relnamespace AND pkc.oid = pka.attrelid AND pka.attnum = con.confkey[pos.n] AND con.confrelid = pkc.oid "+ - " AND fkn.oid = fkc.relnamespace AND fkc.oid = fka.attrelid AND fka.attnum = con.conkey[pos.n] AND con.conrelid = fkc.oid "+ - " AND con.contype = 'f' AND con.oid = dep.objid AND pkic.oid = dep.refobjid AND pkic.relkind = 'i' AND dep.classid = 'pg_constraint'::regclass::oid AND dep.refclassid = 'pg_class'::regclass::oid "; - if (primarySchema != null && !"".equals(primarySchema)) { - sql += " AND pkn.nspname = '"+escapeQuotes(primarySchema)+"' "; - } - if (foreignSchema != null && !"".equals(foreignSchema)) { - sql += " AND fkn.nspname = '"+escapeQuotes(foreignSchema)+"' "; - } - if (primaryTable != null && !"".equals(primaryTable)) { - sql += " AND pkc.relname = '"+escapeQuotes(primaryTable)+"' "; - } - if (foreignTable != null && !"".equals(foreignTable)) { - sql += " AND fkc.relname = '"+escapeQuotes(foreignTable)+"' "; - } - - if (primaryTable != null) { - sql += " ORDER BY fkn.nspname,fkc.relname,pos.n"; - } else { - sql += " ORDER BY pkn.nspname,pkc.relname,pos.n"; - } - - return connection.createStatement().executeQuery(sql); - } else if (connection.haveMinimumServerVersion("7.3")) { - select = "SELECT DISTINCT n1.nspname as pnspname,n2.nspname as fnspname, "; - from = " FROM pg_catalog.pg_namespace n1 "+ - " JOIN pg_catalog.pg_class c1 ON (c1.relnamespace = n1.oid) "+ - " JOIN pg_catalog.pg_index i ON (c1.oid=i.indrelid) "+ - " JOIN pg_catalog.pg_class ic ON (i.indexrelid=ic.oid) "+ - " JOIN pg_catalog.pg_attribute a ON (ic.oid=a.attrelid), "+ - " pg_catalog.pg_namespace n2 "+ - " JOIN pg_catalog.pg_class c2 ON (c2.relnamespace=n2.oid), "+ - " pg_catalog.pg_trigger t1 "+ - " JOIN pg_catalog.pg_proc p1 ON (t1.tgfoid=p1.oid), "+ - " pg_catalog.pg_trigger t2 "+ - " JOIN pg_catalog.pg_proc p2 ON (t2.tgfoid=p2.oid) "; - if (primarySchema != null && !"".equals(primarySchema)) { - where += " AND n1.nspname = '"+escapeQuotes(primarySchema)+"' "; - } - if (foreignSchema != null && !"".equals(foreignSchema)) { - where += " AND n2.nspname = '"+escapeQuotes(foreignSchema)+"' "; - } - } else { - select = "SELECT DISTINCT NULL::text as pnspname, NULL::text as fnspname, "; - from = " FROM pg_class c1 "+ - " JOIN pg_index i ON (c1.oid=i.indrelid) "+ - " JOIN pg_class ic ON (i.indexrelid=ic.oid) "+ - " JOIN pg_attribute a ON (ic.oid=a.attrelid), "+ - " pg_class c2, "+ - " pg_trigger t1 "+ - " JOIN pg_proc p1 ON (t1.tgfoid=p1.oid), "+ - " pg_trigger t2 "+ - " JOIN pg_proc p2 ON (t2.tgfoid=p2.oid) "; - } - - String sql = select - + "c1.relname as prelname, " - + "c2.relname as frelname, " - + "t1.tgconstrname, " - + "a.attnum as keyseq, " - + "ic.relname as fkeyname, " - + "t1.tgdeferrable, " - + "t1.tginitdeferred, " - + "t1.tgnargs,t1.tgargs, " - + "p1.proname as updaterule, " - + "p2.proname as deleterule " - + from - + "WHERE " - // isolate the update rule - + "(t1.tgrelid=c1.oid " - + "AND t1.tgisconstraint " - + "AND t1.tgconstrrelid=c2.oid " - + "AND p1.proname LIKE 'RI\\\\_FKey\\\\_%\\\\_upd') " - - + "AND " - // isolate the delete rule - + "(t2.tgrelid=c1.oid " - + "AND t2.tgisconstraint " - + "AND t2.tgconstrrelid=c2.oid " - + "AND p2.proname LIKE 'RI\\\\_FKey\\\\_%\\\\_del') " - - + "AND i.indisprimary " - + where; - - if (primaryTable != null) { - sql += "AND c1.relname='" + escapeQuotes(primaryTable) + "' "; - } - if (foreignTable != null) { - sql += "AND c2.relname='" + escapeQuotes(foreignTable) + "' "; - } - - sql += "ORDER BY "; - - // orderby is as follows getExported, orders by FKTABLE, - // getImported orders by PKTABLE - // getCrossReference orders by FKTABLE, so this should work for both, - // since when getting crossreference, primaryTable will be defined - - if (primaryTable != null) { - if (connection.haveMinimumServerVersion("7.3")) { - sql += "fnspname,"; - } - sql += "frelname"; - } else { - if (connection.haveMinimumServerVersion("7.3")) { - sql += "pnspname,"; - } - sql += "prelname"; - } - - sql += ",keyseq"; - - ResultSet rs = connection.createStatement().executeQuery(sql); - - // returns the following columns - // and some example data with a table defined as follows - - // create table people ( id int primary key); - // create table policy ( id int primary key); - // create table users ( id int primary key, people_id int references people(id), policy_id int references policy(id)) - - // prelname | frelname | tgconstrname | keyseq | fkeyName | tgdeferrable | tginitdeferred - // 1 | 2 | 3 | 4 | 5 | 6 | 7 - - // people | users | <unnamed> | 1 | people_pkey | f | f - - // | tgnargs | tgargs | updaterule | deleterule - // | 8 | 9 | 10 | 11 - // | 6 | <unnamed>\000users\000people\000UNSPECIFIED\000people_id\000id\000 | RI_FKey_noaction_upd | RI_FKey_noaction_del - - Vector tuples = new Vector(); - - while ( rs.next() ) - { - byte tuple[][] = new byte[14][]; - - tuple[1] = rs.getBytes(1); //PKTABLE_SCHEM - tuple[5] = rs.getBytes(2); //FKTABLE_SCHEM - tuple[2] = rs.getBytes(3); //PKTABLE_NAME - tuple[6] = rs.getBytes(4); //FKTABLE_NAME - String fKeyName = rs.getString(5); - String updateRule = rs.getString(12); - - if (updateRule != null ) - { - // Rules look like this RI_FKey_noaction_del so we want to pull out the part between the 'Key_' and the last '_' s - - String rule = updateRule.substring(8, updateRule.length() - 4); - - int action = java.sql.DatabaseMetaData.importedKeyNoAction; - - if ( rule == null || "noaction".equals(rule) ) - action = java.sql.DatabaseMetaData.importedKeyNoAction; - if ("cascade".equals(rule)) - action = java.sql.DatabaseMetaData.importedKeyCascade; - else if ("setnull".equals(rule)) - action = java.sql.DatabaseMetaData.importedKeySetNull; - else if ("setdefault".equals(rule)) - action = java.sql.DatabaseMetaData.importedKeySetDefault; - else if ("restrict".equals(rule)) - action = java.sql.DatabaseMetaData.importedKeyRestrict; - - tuple[9] = encoding.encode(Integer.toString(action)); - - } - - String deleteRule = rs.getString(13); - - if ( deleteRule != null ) - { - - String rule = deleteRule.substring(8, deleteRule.length() - 4); - - int action = java.sql.DatabaseMetaData.importedKeyNoAction; - if ("cascade".equals(rule)) - action = java.sql.DatabaseMetaData.importedKeyCascade; - else if ("setnull".equals(rule)) - action = java.sql.DatabaseMetaData.importedKeySetNull; - else if ("setdefault".equals(rule)) - action = java.sql.DatabaseMetaData.importedKeySetDefault; - else if ("restrict".equals(rule)) - action = java.sql.DatabaseMetaData.importedKeyRestrict; - tuple[10] = encoding.encode(Integer.toString(action)); - } - - - int keySequence = rs.getInt(6); //KEY_SEQ - - // Parse the tgargs data - String fkeyColumn = ""; - String pkeyColumn = ""; - String fkName = ""; - // Note, I am guessing at most of this, but it should be close - // if not, please correct - // the keys are in pairs and start after the first four arguments - // the arguments are seperated by \000 - - String targs = rs.getString(11); - - // args look like this - //<unnamed>\000ww\000vv\000UNSPECIFIED\000m\000a\000n\000b\000 - // we are primarily interested in the column names which are the last items in the string - - Vector tokens = tokenize(targs, "\\000"); - if (tokens.size() > 0) { - fkName = (String)tokens.elementAt(0); - } - - if (fkName.startsWith("<unnamed>")) { - fkName = targs; - } - - int element = 4 + (keySequence - 1) * 2; - if (tokens.size() > element) { - fkeyColumn = (String)tokens.elementAt(element); - } - - element++; - if (tokens.size() > element) { - pkeyColumn = (String)tokens.elementAt(element); - } - - tuple[3] = encoding.encode(pkeyColumn); //PKCOLUMN_NAME - tuple[7] = encoding.encode(fkeyColumn); //FKCOLUMN_NAME - - tuple[8] = rs.getBytes(6); //KEY_SEQ - tuple[11] = encoding.encode(fkName); //FK_NAME this will give us a unique name for the foreign key - tuple[12] = rs.getBytes(7); //PK_NAME - - // DEFERRABILITY - int deferrability = java.sql.DatabaseMetaData.importedKeyNotDeferrable; - boolean deferrable = rs.getBoolean(8); - boolean initiallyDeferred = rs.getBoolean(9); - if (deferrable) - { - if (initiallyDeferred) - deferrability = java.sql.DatabaseMetaData.importedKeyInitiallyDeferred; - else - deferrability = java.sql.DatabaseMetaData.importedKeyInitiallyImmediate; - } - tuple[13] = encoding.encode(Integer.toString(deferrability)); - - tuples.addElement(tuple); - } - - return (ResultSet) ((BaseStatement)connection.createStatement()).createResultSet(f, tuples, "OK", 1, 0, false); - } - - /* - * Get a description of the primary key columns that are - * referenced by a table's foreign key columns (the primary keys - * imported by a table). They are ordered by PKTABLE_CAT, - * PKTABLE_SCHEM, PKTABLE_NAME, and KEY_SEQ. - * - * <P>Each primary key column description has the following columns: - * <OL> - * <LI><B>PKTABLE_CAT</B> String => primary key table catalog - * being imported (may be null) - * <LI><B>PKTABLE_SCHEM</B> String => primary key table schema - * being imported (may be null) - * <LI><B>PKTABLE_NAME</B> String => primary key table name - * being imported - * <LI><B>PKCOLUMN_NAME</B> String => primary key column name - * being imported - * <LI><B>FKTABLE_CAT</B> String => foreign key table catalog (may be null) - * <LI><B>FKTABLE_SCHEM</B> String => foreign key table schema (may be null) - * <LI><B>FKTABLE_NAME</B> String => foreign key table name - * <LI><B>FKCOLUMN_NAME</B> String => foreign key column name - * <LI><B>KEY_SEQ</B> short => sequence number within foreign key - * <LI><B>UPDATE_RULE</B> short => What happens to - * foreign key when primary is updated: - * <UL> - * <LI> importedKeyCascade - change imported key to agree - * with primary key update - * <LI> importedKeyRestrict - do not allow update of primary - * key if it has been imported - * <LI> importedKeySetNull - change imported key to NULL if - * its primary key has been updated - * </UL> - * <LI><B>DELETE_RULE</B> short => What happens to - * the foreign key when primary is deleted. - * <UL> - * <LI> importedKeyCascade - delete rows that import a deleted key - * <LI> importedKeyRestrict - do not allow delete of primary - * key if it has been imported - * <LI> importedKeySetNull - change imported key to NULL if - * its primary key has been deleted - * </UL> - * <LI><B>FK_NAME</B> String => foreign key name (may be null) - * <LI><B>PK_NAME</B> String => primary key name (may be null) - * </OL> - * - * @param catalog a catalog name; "" retrieves those without a catalog - * @param schema a schema name pattern; "" retrieves those - * without a schema - * @param table a table name - * @return ResultSet each row is a primary key column description - * @see #getExportedKeys - */ - public java.sql.ResultSet getImportedKeys(String catalog, String schema, String table) throws SQLException - { - return getImportedExportedKeys(null,null,null,catalog, schema, table); - } - - /* - * Get a description of a foreign key columns that reference a - * table's primary key columns (the foreign keys exported by a - * table). They are ordered by FKTABLE_CAT, FKTABLE_SCHEM, - * FKTABLE_NAME, and KEY_SEQ. - * - * This method is currently unimplemented. - * - * <P>Each foreign key column description has the following columns: - * <OL> - * <LI><B>PKTABLE_CAT</B> String => primary key table catalog (may be null) - * <LI><B>PKTABLE_SCHEM</B> String => primary key table schema (may be null) - * <LI><B>PKTABLE_NAME</B> String => primary key table name - * <LI><B>PKCOLUMN_NAME</B> String => primary key column name - * <LI><B>FKTABLE_CAT</B> String => foreign key table catalog (may be null) - * being exported (may be null) - * <LI><B>FKTABLE_SCHEM</B> String => foreign key table schema (may be null) - * being exported (may be null) - * <LI><B>FKTABLE_NAME</B> String => foreign key table name - * being exported - * <LI><B>FKCOLUMN_NAME</B> String => foreign key column name - * being exported - * <LI><B>KEY_SEQ</B> short => sequence number within foreign key - * <LI><B>UPDATE_RULE</B> short => What happens to - * foreign key when primary is updated: - * <UL> - * <LI> importedKeyCascade - change imported key to agree - * with primary key update - * <LI> importedKeyRestrict - do not allow update of primary - * key if it has been imported - * <LI> importedKeySetNull - change imported key to NULL if - * its primary key has been updated - * </UL> - * <LI><B>DELETE_RULE</B> short => What happens to - * the foreign key when primary is deleted. - * <UL> - * <LI> importedKeyCascade - delete rows that import a deleted key - * <LI> importedKeyRestrict - do not allow delete of primary - * key if it has been imported - * <LI> importedKeySetNull - change imported key to NULL if - * its primary key has been deleted - * </UL> - * <LI><B>FK_NAME</B> String => foreign key identifier (may be null) - * <LI><B>PK_NAME</B> String => primary key identifier (may be null) - * </OL> - * - * @param catalog a catalog name; "" retrieves those without a catalog - * @param schema a schema name pattern; "" retrieves those - * without a schema - * @param table a table name - * @return ResultSet each row is a foreign key column description - * @see #getImportedKeys - */ - public java.sql.ResultSet getExportedKeys(String catalog, String schema, String table) throws SQLException - { - return getImportedExportedKeys(catalog, schema, table, null,null,null); - } - - /* - * Get a description of the foreign key columns in the foreign key - * table that reference the primary key columns of the primary key - * table (describe how one table imports another's key.) This - * should normally return a single foreign key/primary key pair - * (most tables only import a foreign key from a table once.) They - * are ordered by FKTABLE_CAT, FKTABLE_SCHEM, FKTABLE_NAME, and - * KEY_SEQ. - * - * This method is currently unimplemented. - * - * <P>Each foreign key column description has the following columns: - * <OL> - * <LI><B>PKTABLE_CAT</B> String => primary key table catalog (may be null) - * <LI><B>PKTABLE_SCHEM</B> String => primary key table schema (may be null) - * <LI><B>PKTABLE_NAME</B> String => primary key table name - * <LI><B>PKCOLUMN_NAME</B> String => primary key column name - * <LI><B>FKTABLE_CAT</B> String => foreign key table catalog (may be null) - * being exported (may be null) - * <LI><B>FKTABLE_SCHEM</B> String => foreign key table schema (may be null) - * being exported (may be null) - * <LI><B>FKTABLE_NAME</B> String => foreign key table name - * being exported - * <LI><B>FKCOLUMN_NAME</B> String => foreign key column name - * being exported - * <LI><B>KEY_SEQ</B> short => sequence number within foreign key - * <LI><B>UPDATE_RULE</B> short => What happens to - * foreign key when primary is updated: - * <UL> - * <LI> importedKeyCascade - change imported key to agree - * with primary key update - * <LI> importedKeyRestrict - do not allow update of primary - * key if it has been imported - * <LI> importedKeySetNull - change imported key to NULL if - * its primary key has been updated - * </UL> - * <LI><B>DELETE_RULE</B> short => What happens to - * the foreign key when primary is deleted. - * <UL> - * <LI> importedKeyCascade - delete rows that import a deleted key - * <LI> importedKeyRestrict - do not allow delete of primary - * key if it has been imported - * <LI> importedKeySetNull - change imported key to NULL if - * its primary key has been deleted - * </UL> - * <LI><B>FK_NAME</B> String => foreign key identifier (may be null) - * <LI><B>PK_NAME</B> String => primary key identifier (may be null) - * </OL> - * - * @param catalog a catalog name; "" retrieves those without a catalog - * @param schema a schema name pattern; "" retrieves those - * without a schema - * @param table a table name - * @return ResultSet each row is a foreign key column description - * @see #getImportedKeys - */ - public java.sql.ResultSet getCrossReference(String primaryCatalog, String primarySchema, String primaryTable, String foreignCatalog, String foreignSchema, String foreignTable) throws SQLException - { - return getImportedExportedKeys(primaryCatalog, primarySchema, primaryTable, foreignCatalog, foreignSchema, foreignTable); - } - - /* - * Get a description of all the standard SQL types supported by - * this database. They are ordered by DATA_TYPE and then by how - * closely the data type maps to the corresponding JDBC SQL type. - * - * <P>Each type description has the following columns: - * <OL> - * <LI><B>TYPE_NAME</B> String => Type name - * <LI><B>DATA_TYPE</B> short => SQL data type from java.sql.Types - * <LI><B>PRECISION</B> int => maximum precision - * <LI><B>LITERAL_PREFIX</B> String => prefix used to quote a literal - * (may be null) - * <LI><B>LITERAL_SUFFIX</B> String => suffix used to quote a literal - (may be null) - * <LI><B>CREATE_PARAMS</B> String => parameters used in creating - * the type (may be null) - * <LI><B>NULLABLE</B> short => can you use NULL for this type? - * <UL> - * <LI> typeNoNulls - does not allow NULL values - * <LI> typeNullable - allows NULL values - * <LI> typeNullableUnknown - nullability unknown - * </UL> - * <LI><B>CASE_SENSITIVE</B> boolean=> is it case sensitive? - * <LI><B>SEARCHABLE</B> short => can you use "WHERE" based on this type: - * <UL> - * <LI> typePredNone - No support - * <LI> typePredChar - Only supported with WHERE .. LIKE - * <LI> typePredBasic - Supported except for WHERE .. LIKE - * <LI> typeSearchable - Supported for all WHERE .. - * </UL> - * <LI><B>UNSIGNED_ATTRIBUTE</B> boolean => is it unsigned? - * <LI><B>FIXED_PREC_SCALE</B> boolean => can it be a money value? - * <LI><B>AUTO_INCREMENT</B> boolean => can it be used for an - * auto-increment value? - * <LI><B>LOCAL_TYPE_NAME</B> String => localized version of type name - * (may be null) - * <LI><B>MINIMUM_SCALE</B> short => minimum scale supported - * <LI><B>MAXIMUM_SCALE</B> short => maximum scale supported - * <LI><B>SQL_DATA_TYPE</B> int => unused - * <LI><B>SQL_DATETIME_SUB</B> int => unused - * <LI><B>NUM_PREC_RADIX</B> int => usually 2 or 10 - * </OL> - * - * @return ResultSet each row is a SQL type description - */ - public java.sql.ResultSet getTypeInfo() throws SQLException - { - - Field f[] = new Field[18]; - Vector v = new Vector(); // The new ResultSet tuple stuff - - f[0] = new Field(connection, "TYPE_NAME", iVarcharOid, getMaxNameLength()); - f[1] = new Field(connection, "DATA_TYPE", iInt2Oid, 2); - f[2] = new Field(connection, "PRECISION", iInt4Oid, 4); - f[3] = new Field(connection, "LITERAL_PREFIX", iVarcharOid, getMaxNameLength()); - f[4] = new Field(connection, "LITERAL_SUFFIX", iVarcharOid, getMaxNameLength()); - f[5] = new Field(connection, "CREATE_PARAMS", iVarcharOid, getMaxNameLength()); - f[6] = new Field(connection, "NULLABLE", iInt2Oid, 2); - f[7] = new Field(connection, "CASE_SENSITIVE", iBoolOid, 1); - f[8] = new Field(connection, "SEARCHABLE", iInt2Oid, 2); - f[9] = new Field(connection, "UNSIGNED_ATTRIBUTE", iBoolOid, 1); - f[10] = new Field(connection, "FIXED_PREC_SCALE", iBoolOid, 1); - f[11] = new Field(connection, "AUTO_INCREMENT", iBoolOid, 1); - f[12] = new Field(connection, "LOCAL_TYPE_NAME", iVarcharOid, getMaxNameLength()); - f[13] = new Field(connection, "MINIMUM_SCALE", iInt2Oid, 2); - f[14] = new Field(connection, "MAXIMUM_SCALE", iInt2Oid, 2); - f[15] = new Field(connection, "SQL_DATA_TYPE", iInt4Oid, 4); - f[16] = new Field(connection, "SQL_DATETIME_SUB", iInt4Oid, 4); - f[17] = new Field(connection, "NUM_PREC_RADIX", iInt4Oid, 4); - - String sql; - if (connection.haveMinimumServerVersion("7.3")) { - sql = "SELECT typname FROM pg_catalog.pg_type"; - } else { - sql = "SELECT typname FROM pg_type"; - } - - ResultSet rs = connection.createStatement().executeQuery(sql); - // cache some results, this will keep memory useage down, and speed - // things up a little. - byte b9[] = encoding.encode("9"); - byte b10[] = encoding.encode("10"); - byte bf[] = encoding.encode("f"); - byte bnn[] = encoding.encode(Integer.toString(java.sql.DatabaseMetaData.typeNoNulls)); - byte bts[] = encoding.encode(Integer.toString(java.sql.DatabaseMetaData.typeSearchable)); - - while (rs.next()) - { - byte[][] tuple = new byte[18][]; - String typname = rs.getString(1); - tuple[0] = encoding.encode(typname); - tuple[1] = encoding.encode(Integer.toString(connection.getSQLType(typname))); - tuple[2] = b9; // for now - tuple[6] = bnn; // for now - tuple[7] = bf; // false for now - not case sensitive - tuple[8] = bts; - tuple[9] = bf; // false for now - it's signed - tuple[10] = bf; // false for now - must handle money - tuple[11] = bf; // false for now - handle autoincrement - // 12 - LOCAL_TYPE_NAME is null - // 13 & 14 ? - // 15 & 16 are unused so we return null - tuple[17] = b10; // everything is base 10 - v.addElement(tuple); - } - rs.close(); - - return (ResultSet) ((BaseStatement)connection.createStatement()).createResultSet(f, v, "OK", 1, 0, false); - } - - /* - * Get a description of a table's indices and statistics. They are - * ordered by NON_UNIQUE, TYPE, INDEX_NAME, and ORDINAL_POSITION. - * - * <P>Each index column description has the following columns: - * <OL> - * <LI><B>TABLE_CAT</B> String => table catalog (may be null) - * <LI><B>TABLE_SCHEM</B> String => table schema (may be null) - * <LI><B>TABLE_NAME</B> String => table name - * <LI><B>NON_UNIQUE</B> boolean => Can index values be non-unique? - * false when TYPE is tableIndexStatistic - * <LI><B>INDEX_QUALIFIER</B> String => index catalog (may be null); - * null when TYPE is tableIndexStatistic - * <LI><B>INDEX_NAME</B> String => index name; null when TYPE is - * tableIndexStatistic - * <LI><B>TYPE</B> short => index type: - * <UL> - * <LI> tableIndexStatistic - this identifies table statistics that are - * returned in conjuction with a table's index descriptions - * <LI> tableIndexClustered - this is a clustered index - * <LI> tableIndexHashed - this is a hashed index - * <LI> tableIndexOther - this is some other style of index - * </UL> - * <LI><B>ORDINAL_POSITION</B> short => column sequence number - * within index; zero when TYPE is tableIndexStatistic - * <LI><B>COLUMN_NAME</B> String => column name; null when TYPE is - * tableIndexStatistic - * <LI><B>ASC_OR_DESC</B> String => column sort sequence, "A" => ascending - * "D" => descending, may be null if sort sequence is not supported; - * null when TYPE is tableIndexStatistic - * <LI><B>CARDINALITY</B> int => When TYPE is tableIndexStatisic then - * this is the number of rows in the table; otherwise it is the - * number of unique values in the index. - * <LI><B>PAGES</B> int => When TYPE is tableIndexStatisic then - * this is the number of pages used for the table, otherwise it - * is the number of pages used for the current index. - * <LI><B>FILTER_CONDITION</B> String => Filter condition, if any. - * (may be null) - * </OL> - * - * @param catalog a catalog name; "" retrieves those without a catalog - * @param schema a schema name pattern; "" retrieves those without a schema - * @param table a table name - * @param unique when true, return only indices for unique values; - * when false, return indices regardless of whether unique or not - * @param approximate when true, result is allowed to reflect approximate - * or out of data values; when false, results are requested to be - * accurate - * @return ResultSet each row is an index column description - */ - // Implementation note: This is required for Borland's JBuilder to work - public java.sql.ResultSet getIndexInfo(String catalog, String schema, String tableName, boolean unique, boolean approximate) throws SQLException - { - String select; - String from; - String where = ""; - if (connection.haveMinimumServerVersion("7.3")) { - select = "SELECT NULL AS TABLE_CAT, n.nspname AS TABLE_SCHEM, "; - from = " FROM pg_catalog.pg_namespace n, pg_catalog.pg_class ct, pg_catalog.pg_class ci, pg_catalog.pg_index i, pg_catalog.pg_attribute a, pg_catalog.pg_am am "; - where = " AND n.oid = ct.relnamespace "; - if (schema != null && ! "".equals(schema)) { - where += " AND n.nspname = '"+escapeQuotes(schema)+"' "; - } - } else { - select = "SELECT NULL AS TABLE_CAT, NULL AS TABLE_SCHEM, "; - from = " FROM pg_class ct, pg_class ci, pg_index i, pg_attribute a, pg_am am "; - } - - String sql = select+ - " ct.relname AS TABLE_NAME, NOT i.indisunique AS NON_UNIQUE, NULL AS INDEX_QUALIFIER, ci.relname AS INDEX_NAME, "+ - " CASE i.indisclustered "+ - " WHEN true THEN "+java.sql.DatabaseMetaData.tableIndexClustered+ - " ELSE CASE am.amname "+ - " WHEN 'hash' THEN "+java.sql.DatabaseMetaData.tableIndexHashed+ - " ELSE "+java.sql.DatabaseMetaData.tableIndexOther+ - " END "+ - " END AS TYPE, "+ - " a.attnum AS ORDINAL_POSITION, "+ - " a.attname AS COLUMN_NAME, "+ - " NULL AS ASC_OR_DESC, "+ - " ci.reltuples AS CARDINALITY, "+ - " ci.relpages AS PAGES, "+ - " NULL AS FILTER_CONDITION "+ - from+ - " WHERE ct.oid=i.indrelid AND ci.oid=i.indexrelid AND a.attrelid=ci.oid AND ci.relam=am.oid "+ - where+ - " AND ct.relname = '"+escapeQuotes(tableName)+"' "; - - if (unique) { - sql += " AND i.indisunique "; - } - sql += " ORDER BY NON_UNIQUE, TYPE, INDEX_NAME, ORDINAL_POSITION "; - return connection.createStatement().executeQuery(sql); - } - - /** - * Tokenize based on words not on single characters. - */ - private static Vector tokenize(String input, String delimiter) { - Vector result = new Vector(); - int start = 0; - int end = input.length(); - int delimiterSize = delimiter.length(); - - while (start < end) { - int delimiterIndex = input.indexOf(delimiter,start); - if (delimiterIndex < 0) { - result.addElement(input.substring(start)); - break; - } else { - String token = input.substring(start,delimiterIndex); - result.addElement(token); - start = delimiterIndex + delimiterSize; - } - } - return result; - } - - - -} diff --git a/src/interfaces/jdbc/org/postgresql/jdbc1/AbstractJdbc1ResultSet.java b/src/interfaces/jdbc/org/postgresql/jdbc1/AbstractJdbc1ResultSet.java deleted file mode 100644 index 42cde402868..00000000000 --- a/src/interfaces/jdbc/org/postgresql/jdbc1/AbstractJdbc1ResultSet.java +++ /dev/null @@ -1,1255 +0,0 @@ -/*------------------------------------------------------------------------- - * - * AbstractJdbc1ResultSet.java - * This class defines methods of the jdbc1 specification. This class is - * extended by org.postgresql.jdbc2.AbstractJdbc2ResultSet which adds the - * jdbc2 methods. The real ResultSet class (for jdbc1) is - * org.postgresql.jdbc1.Jdbc1ResultSet - * - * Copyright (c) 2003, PostgreSQL Global Development Group - * - * IDENTIFICATION - * $PostgreSQL: pgsql/src/interfaces/jdbc/org/postgresql/jdbc1/AbstractJdbc1ResultSet.java,v 1.25 2003/12/12 17:58:34 davec Exp $ - * - *------------------------------------------------------------------------- - */ -package org.postgresql.jdbc1; - -import java.math.BigDecimal; -import java.io.*; -import java.sql.*; -import java.text.ParseException; -import java.text.SimpleDateFormat; -import java.util.Vector; -import org.postgresql.Driver; -import org.postgresql.core.BaseConnection; -import org.postgresql.core.BaseResultSet; -import org.postgresql.core.BaseStatement; -import org.postgresql.core.Field; -import org.postgresql.core.Encoding; -import org.postgresql.core.QueryExecutor; -import org.postgresql.largeobject.*; -import org.postgresql.util.PGbytea; -import org.postgresql.util.PGtokenizer; -import org.postgresql.util.PSQLException; -import org.postgresql.util.PSQLState; - -public abstract class AbstractJdbc1ResultSet implements BaseResultSet -{ - - protected Vector rows; // The results - protected BaseStatement statement; - protected Field fields[]; // The field descriptions - protected String status; // Status of the result - protected boolean binaryCursor = false; // is the data binary or Strings - protected int updateCount; // How many rows did we get back? - protected long insertOID; // The oid of an inserted row - protected int current_row; // Our pointer to where we are at - protected byte[][] this_row; // the current row result - protected BaseConnection connection; // the connection which we returned from - protected SQLWarning warnings = null; // The warning chain - protected boolean wasNullFlag = false; // the flag for wasNull() - - // We can chain multiple resultSets together - this points to - // next resultSet in the chain. - protected BaseResultSet next = null; - - private StringBuffer sbuf = null; - public byte[][] rowBuffer = null; - - private SimpleDateFormat m_tsFormat = null; - private SimpleDateFormat m_tstzFormat = null; - private SimpleDateFormat m_dateFormat = null; - - private int fetchSize; // Fetch size for next read (might be 0). - private int lastFetchSize; // Fetch size of last read (might be 0). - - public abstract ResultSetMetaData getMetaData() throws SQLException; - - public AbstractJdbc1ResultSet(BaseStatement statement, - Field[] fields, - Vector tuples, - String status, - int updateCount, - long insertOID, - boolean binaryCursor) - { - this.connection = statement.getPGConnection(); - this.statement = statement; - this.fields = fields; - this.rows = tuples; - this.status = status; - this.updateCount = updateCount; - - this.insertOID = insertOID; - this.this_row = null; - this.current_row = -1; - this.binaryCursor = binaryCursor; - - this.lastFetchSize = this.fetchSize = (statement == null ? 0 : statement.getFetchSize()); - } - - public BaseStatement getPGStatement() { - return statement; - } - - public StringBuffer getStringBuffer() { - return sbuf; - } - - //This is implemented in jdbc2 - public void setStatement(BaseStatement statement) { - } - - //method to reinitialize a result set with more data - public void reInit (Field[] fields, Vector tuples, String status, - int updateCount, long insertOID, boolean binaryCursor) - { - this.fields = fields; - // on a reinit the size of this indicates how many we pulled - // back. If it's 0 then the res set has ended. - this.rows = tuples; - this.status = status; - this.updateCount = updateCount; - this.insertOID = insertOID; - this.this_row = null; - this.current_row = -1; - this.binaryCursor = binaryCursor; - } - - // - // Part of the JDBC2 support, but convenient to implement here. - // - - public void setFetchSize(int rows) throws SQLException - { - fetchSize = rows; - } - - - public int getFetchSize() throws SQLException - { - return fetchSize; - } - - public boolean next() throws SQLException - { - if (rows == null) - throw new PSQLException("postgresql.con.closed", PSQLState.CONNECTION_DOES_NOT_EXIST); - - if (++current_row >= rows.size()) - { - String cursorName = statement.getFetchingCursorName(); - if (cursorName == null || lastFetchSize == 0 || rows.size() < lastFetchSize) - return false; // Not doing a cursor-based fetch or the last fetch was the end of the query - - // Use the ref to the statement to get - // the details we need to do another cursor - // query - it will use reinit() to repopulate this - // with the right data. - - // NB: We can reach this point with fetchSize == 0 - // if the fetch size is changed halfway through reading results. - // Use "FETCH FORWARD ALL" in that case to complete the query. - String[] sql = new String[] { - fetchSize == 0 ? ("FETCH FORWARD ALL FROM " + cursorName) : - ("FETCH FORWARD " + fetchSize + " FROM " + cursorName) - }; - - QueryExecutor.execute(sql, - new String[0], - this); - - // Test the new rows array. - lastFetchSize = fetchSize; - if (rows.size() == 0) - return false; - - // Otherwise reset the counter and let it go on... - current_row = 0; - } - - this_row = (byte [][])rows.elementAt(current_row); - - rowBuffer = new byte[this_row.length][]; - System.arraycopy(this_row, 0, rowBuffer, 0, this_row.length); - return true; - } - - public void close() throws SQLException - { - //release resources held (memory for tuples) - if (rows != null) - { - rows = null; - } - } - - public boolean wasNull() throws SQLException - { - return wasNullFlag; - } - - public String getString(int columnIndex) throws SQLException - { - checkResultSet( columnIndex ); - wasNullFlag = (this_row[columnIndex - 1] == null); - if (wasNullFlag) - return null; - - Encoding encoding = connection.getEncoding(); - return trimString(columnIndex, encoding.decode(this_row[columnIndex-1])); - } - - public boolean getBoolean(int columnIndex) throws SQLException - { - return toBoolean( getString(columnIndex) ); - } - - - public byte getByte(int columnIndex) throws SQLException - { - String s = getString(columnIndex); - - if (s != null ) - { - try - { - switch(fields[columnIndex-1].getSQLType()) - { - case Types.NUMERIC: - case Types.REAL: - case Types.DOUBLE: - case Types.FLOAT: - case Types.DECIMAL: - int loc = s.indexOf("."); - if (loc!=-1 && Integer.parseInt(s.substring(loc+1,s.length()))==0) - { - s = s.substring(0,loc); - } - break; - case Types.CHAR: - s = s.trim(); - break; - } - if ( s.length() == 0 ) return 0; - return Byte.parseByte(s); - } - catch (NumberFormatException e) - { - throw new PSQLException("postgresql.res.badbyte", PSQLState.NUMERIC_VALUE_OUT_OF_RANGE, s); - } - } - return 0; // SQL NULL - } - - public short getShort(int columnIndex) throws SQLException - { - String s = getFixedString(columnIndex); - - if (s != null) - { - try - { - switch(fields[columnIndex-1].getSQLType()) - { - case Types.NUMERIC: - case Types.REAL: - case Types.DOUBLE: - case Types.FLOAT: - case Types.DECIMAL: - int loc = s.indexOf("."); - if (loc!=-1 && Integer.parseInt(s.substring(loc+1,s.length()))==0) - { - s = s.substring(0,loc); - } - break; - case Types.CHAR: - s = s.trim(); - break; - } - return Short.parseShort(s); - } - catch (NumberFormatException e) - { - throw new PSQLException("postgresql.res.badshort", PSQLState.NUMERIC_VALUE_OUT_OF_RANGE, s); - } - } - return 0; // SQL NULL - } - - public int getInt(int columnIndex) throws SQLException - { - return toInt( getFixedString(columnIndex) ); - } - - public long getLong(int columnIndex) throws SQLException - { - return toLong( getFixedString(columnIndex) ); - } - - public float getFloat(int columnIndex) throws SQLException - { - return toFloat( getFixedString(columnIndex) ); - } - - public double getDouble(int columnIndex) throws SQLException - { - return toDouble( getFixedString(columnIndex) ); - } - - public BigDecimal getBigDecimal(int columnIndex, int scale) throws SQLException - { - return toBigDecimal( getFixedString(columnIndex), scale ); - } - - /* - * Get the value of a column in the current row as a Java byte array. - * - * <p>In normal use, the bytes represent the raw values returned by the - * backend. However, if the column is an OID, then it is assumed to - * refer to a Large Object, and that object is returned as a byte array. - * - * <p><b>Be warned</b> If the large object is huge, then you may run out - * of memory. - * - * @param columnIndex the first column is 1, the second is 2, ... - * @return the column value; if the value is SQL NULL, the result - * is null - * @exception SQLException if a database access error occurs - */ - public byte[] getBytes(int columnIndex) throws SQLException - { - checkResultSet( columnIndex ); - wasNullFlag = (this_row[columnIndex - 1] == null); - if (!wasNullFlag) - { - if (binaryCursor) - { - //If the data is already binary then just return it - return this_row[columnIndex - 1]; - } - else if (connection.haveMinimumCompatibleVersion("7.2")) - { - //Version 7.2 supports the bytea datatype for byte arrays - if (fields[columnIndex - 1].getPGType().equals("bytea")) - { - return trimBytes(columnIndex, PGbytea.toBytes(this_row[columnIndex - 1])); - } - else - { - return trimBytes(columnIndex, this_row[columnIndex - 1]); - } - } - else - { - //Version 7.1 and earlier supports LargeObjects for byte arrays - // Handle OID's as BLOBS - if ( fields[columnIndex - 1].getOID() == 26) - { - LargeObjectManager lom = connection.getLargeObjectAPI(); - LargeObject lob = lom.open(getInt(columnIndex)); - byte buf[] = lob.read(lob.size()); - lob.close(); - return trimBytes(columnIndex, buf); - } - else - { - return trimBytes(columnIndex, this_row[columnIndex - 1]); - } - } - } - return null; - } - - public java.sql.Date getDate(int columnIndex) throws SQLException - { - return toDate( getString(columnIndex) ); - } - - public Time getTime(int columnIndex) throws SQLException - { - return toTime( getString(columnIndex), this, fields[columnIndex - 1].getPGType() ); - } - - public Timestamp getTimestamp(int columnIndex) throws SQLException - { - return toTimestamp( getString(columnIndex), this, fields[columnIndex - 1].getPGType() ); - } - - public InputStream getAsciiStream(int columnIndex) throws SQLException - { - checkResultSet( columnIndex ); - wasNullFlag = (this_row[columnIndex - 1] == null); - if (wasNullFlag) - return null; - - if (connection.haveMinimumCompatibleVersion("7.2")) - { - //Version 7.2 supports AsciiStream for all the PG text types - //As the spec/javadoc for this method indicate this is to be used for - //large text values (i.e. LONGVARCHAR) PG doesn't have a separate - //long string datatype, but with toast the text datatype is capable of - //handling very large values. Thus the implementation ends up calling - //getString() since there is no current way to stream the value from the server - try - { - return new ByteArrayInputStream(getString(columnIndex).getBytes("ASCII")); - } - catch (UnsupportedEncodingException l_uee) - { - throw new PSQLException("postgresql.unusual", PSQLState.UNEXPECTED_ERROR, l_uee); - } - } - else - { - // In 7.1 Handle as BLOBS so return the LargeObject input stream - return getBinaryStream(columnIndex); - } - } - - public InputStream getUnicodeStream(int columnIndex) throws SQLException - { - checkResultSet( columnIndex ); - wasNullFlag = (this_row[columnIndex - 1] == null); - if (wasNullFlag) - return null; - - if (connection.haveMinimumCompatibleVersion("7.2")) - { - //Version 7.2 supports AsciiStream for all the PG text types - //As the spec/javadoc for this method indicate this is to be used for - //large text values (i.e. LONGVARCHAR) PG doesn't have a separate - //long string datatype, but with toast the text datatype is capable of - //handling very large values. Thus the implementation ends up calling - //getString() since there is no current way to stream the value from the server - try - { - return new ByteArrayInputStream(getString(columnIndex).getBytes("UTF-8")); - } - catch (UnsupportedEncodingException l_uee) - { - throw new PSQLException("postgresql.unusual", PSQLState.UNEXPECTED_ERROR, l_uee); - } - } - else - { - // In 7.1 Handle as BLOBS so return the LargeObject input stream - return getBinaryStream(columnIndex); - } - } - - public InputStream getBinaryStream(int columnIndex) throws SQLException - { - checkResultSet( columnIndex ); - wasNullFlag = (this_row[columnIndex - 1] == null); - if (wasNullFlag) - return null; - - if (connection.haveMinimumCompatibleVersion("7.2")) - { - //Version 7.2 supports BinaryStream for all PG bytea type - //As the spec/javadoc for this method indicate this is to be used for - //large binary values (i.e. LONGVARBINARY) PG doesn't have a separate - //long binary datatype, but with toast the bytea datatype is capable of - //handling very large values. Thus the implementation ends up calling - //getBytes() since there is no current way to stream the value from the server - byte b[] = getBytes(columnIndex); - if (b != null) - return new ByteArrayInputStream(b); - } - else - { - // In 7.1 Handle as BLOBS so return the LargeObject input stream - if ( fields[columnIndex - 1].getOID() == 26) - { - LargeObjectManager lom = connection.getLargeObjectAPI(); - LargeObject lob = lom.open(getInt(columnIndex)); - return lob.getInputStream(); - } - } - return null; - } - - public String getString(String columnName) throws SQLException - { - return getString(findColumn(columnName)); - } - - public boolean getBoolean(String columnName) throws SQLException - { - return getBoolean(findColumn(columnName)); - } - - public byte getByte(String columnName) throws SQLException - { - - return getByte(findColumn(columnName)); - } - - public short getShort(String columnName) throws SQLException - { - return getShort(findColumn(columnName)); - } - - public int getInt(String columnName) throws SQLException - { - return getInt(findColumn(columnName)); - } - - public long getLong(String columnName) throws SQLException - { - return getLong(findColumn(columnName)); - } - - public float getFloat(String columnName) throws SQLException - { - return getFloat(findColumn(columnName)); - } - - public double getDouble(String columnName) throws SQLException - { - return getDouble(findColumn(columnName)); - } - - public BigDecimal getBigDecimal(String columnName, int scale) throws SQLException - { - return getBigDecimal(findColumn(columnName), scale); - } - - public byte[] getBytes(String columnName) throws SQLException - { - return getBytes(findColumn(columnName)); - } - - public java.sql.Date getDate(String columnName) throws SQLException - { - return getDate(findColumn(columnName)); - } - - public Time getTime(String columnName) throws SQLException - { - return getTime(findColumn(columnName)); - } - - public Timestamp getTimestamp(String columnName) throws SQLException - { - return getTimestamp(findColumn(columnName)); - } - - public InputStream getAsciiStream(String columnName) throws SQLException - { - return getAsciiStream(findColumn(columnName)); - } - - public InputStream getUnicodeStream(String columnName) throws SQLException - { - return getUnicodeStream(findColumn(columnName)); - } - - public InputStream getBinaryStream(String columnName) throws SQLException - { - return getBinaryStream(findColumn(columnName)); - } - - public SQLWarning getWarnings() throws SQLException - { - return warnings; - } - - public void clearWarnings() throws SQLException - { - warnings = null; - } - - public void addWarnings(SQLWarning warnings) - { - if ( this.warnings != null ) - this.warnings.setNextWarning(warnings); - else - this.warnings = warnings; - } - - public String getCursorName() throws SQLException - { - return (connection.getCursorName()); - } - - /* - * Get the value of a column in the current row as a Java object - * - * <p>This method will return the value of the given column as a - * Java object. The type of the Java object will be the default - * Java Object type corresponding to the column's SQL type, following - * the mapping specified in the JDBC specification. - * - * <p>This method may also be used to read database specific abstract - * data types. - * - * @param columnIndex the first column is 1, the second is 2... - * @return a Object holding the column value - * @exception SQLException if a database access error occurs - */ - public Object getObject(int columnIndex) throws SQLException - { - Field field; - - if (columnIndex < 1 || columnIndex > fields.length) - throw new PSQLException("postgresql.res.colrange", PSQLState.INVALID_PARAMETER_VALUE); - field = fields[columnIndex - 1]; - - // some fields can be null, mainly from those returned by MetaData methods - if (field == null) - { - wasNullFlag = true; - return null; - } - - switch (field.getSQLType()) - { - case Types.BIT: - return getBoolean(columnIndex) ? Boolean.TRUE : Boolean.FALSE; - case Types.SMALLINT: - return new Short(getShort(columnIndex)); - case Types.INTEGER: - return new Integer(getInt(columnIndex)); - case Types.BIGINT: - return new Long(getLong(columnIndex)); - case Types.NUMERIC: - return getBigDecimal - (columnIndex, (field.getMod() == -1) ? -1 : ((field.getMod() - 4) & 0xffff)); - case Types.REAL: - return new Float(getFloat(columnIndex)); - case Types.DOUBLE: - return new Double(getDouble(columnIndex)); - case Types.CHAR: - case Types.VARCHAR: - return getString(columnIndex); - case Types.DATE: - return getDate(columnIndex); - case Types.TIME: - return getTime(columnIndex); - case Types.TIMESTAMP: - return getTimestamp(columnIndex); - case Types.BINARY: - case Types.VARBINARY: - return getBytes(columnIndex); - default: - String type = field.getPGType(); - - // if the backend doesn't know the type then coerce to String - if (type.equals("unknown")) - { - return getString(columnIndex); - } - // Specialized support for ref cursors is neater. - else if (type.equals("refcursor")) - { - String cursorName = getString(columnIndex); - return statement.createRefCursorResultSet(cursorName); - } - else - { - return connection.getObject(field.getPGType(), getString(columnIndex)); - } - } - } - - public Object getObject(String columnName) throws SQLException - { - return getObject(findColumn(columnName)); - } - - /* - * Map a ResultSet column name to a ResultSet column index - */ - public int findColumn(String columnName) throws SQLException - { - int i; - - final int flen = fields.length; - for (i = 0 ; i < flen; ++i) - if (fields[i].getName().equalsIgnoreCase(columnName)) - return (i + 1); - throw new PSQLException ("postgresql.res.colname", columnName); - } - - - /* - * We at times need to know if the resultSet we are working - * with is the result of an UPDATE, DELETE or INSERT (in which - * case, we only have a row count), or of a SELECT operation - * (in which case, we have multiple fields) - this routine - * tells us. - */ - public boolean reallyResultSet() - { - return (fields != null); - } - - /* - * Since ResultSets can be chained, we need some method of - * finding the next one in the chain. The method getNext() - * returns the next one in the chain. - * - * @return the next ResultSet, or null if there are none - */ - public ResultSet getNext() - { - return (ResultSet)next; - } - - /* - * This following method allows us to add a ResultSet object - * to the end of the current chain. - */ - public void append(BaseResultSet r) - { - if (next == null) - next = r; - else - next.append(r); - } - - /* - * If we are just a place holder for results, we still need - * to get an updateCount. This method returns it. - */ - public int getResultCount() - { - return updateCount; - } - - /* - * We also need to provide a couple of auxiliary functions for - * the implementation of the ResultMetaData functions. In - * particular, we need to know the number of rows and the - * number of columns. Rows are also known as Tuples - */ - public int getTupleCount() - { - return rows.size(); - } - - /* - * getColumnCount returns the number of columns - */ - public int getColumnCount() - { - return fields.length; - } - - /* - * Returns the status message from the backend.<p> - * It is used internally by the driver. - */ - public String getStatusString() - { - return status; - } - - /* - * returns the OID of a field.<p> - * It is used internally by the driver. - */ - public int getColumnOID(int field) - { - return fields[field -1].getOID(); - } - - /* - * returns the OID of the last inserted row. Deprecated in 7.2 because - * range for OID values is greater than java signed int. - * @deprecated Replaced by getLastOID() in 7.2 - */ - public int getInsertedOID() - { - return (int) getLastOID(); - } - - - /* - * returns the OID of the last inserted row - * @since 7.2 - */ - public long getLastOID() - { - return insertOID; - } - - /* - * This is used to fix get*() methods on Money fields. It should only be - * used by those methods! - * - * It converts ($##.##) to -##.## and $##.## to ##.## - */ - public String getFixedString(int col) throws SQLException - { - String s = getString(col); - - // Handle SQL Null - wasNullFlag = (this_row[col - 1] == null); - if (wasNullFlag) - return null; - - // if we don't have at least 2 characters it can't be money. - if (s.length() < 2) - return s; - - // Handle Money - if (s.charAt(0) == '(') - { - s = "-" + PGtokenizer.removePara(s).substring(1); - } - if (s.charAt(0) == '$') - { - s = s.substring(1); - } - else if (s.charAt(0) == '-' && s.charAt(1) == '$') - { - s = "-" + s.substring(2); - } - - return s; - } - - protected void checkResultSet( int column ) throws SQLException - { - if ( this_row == null ) - throw new PSQLException("postgresql.res.nextrequired"); - if ( column < 1 || column > fields.length ) - throw new PSQLException("postgresql.res.colrange", PSQLState.INVALID_PARAMETER_VALUE ); - } - - //----------------- Formatting Methods ------------------- - - public static boolean toBoolean(String s) - { - if (s != null) - { - s = s.trim(); - - if (s.equalsIgnoreCase("true") || s.equalsIgnoreCase("t")) - return true; - - try - { - if (Double.valueOf(s).doubleValue()==1) - return true; - } - catch (NumberFormatException e) - { - } - } - return false; // SQL NULL - } - - public static int toInt(String s) throws SQLException - { - if (s != null) - { - try - { - s = s.trim(); - return Integer.parseInt(s); - } - catch (NumberFormatException e) - { - throw new PSQLException ("postgresql.res.badint", PSQLState.NUMERIC_VALUE_OUT_OF_RANGE, s); - } - } - return 0; // SQL NULL - } - - public static long toLong(String s) throws SQLException - { - if (s != null) - { - try - { - s = s.trim(); - return Long.parseLong(s); - } - catch (NumberFormatException e) - { - throw new PSQLException ("postgresql.res.badlong", PSQLState.NUMERIC_VALUE_OUT_OF_RANGE, s); - } - } - return 0; // SQL NULL - } - - public static BigDecimal toBigDecimal(String s, int scale) throws SQLException - { - BigDecimal val; - if (s != null) - { - try - { - s = s.trim(); - val = new BigDecimal(s); - } - catch (NumberFormatException e) - { - throw new PSQLException ("postgresql.res.badbigdec", PSQLState.NUMERIC_VALUE_OUT_OF_RANGE, s); - } - if (scale == -1) - return val; - try - { - return val.setScale(scale); - } - catch (ArithmeticException e) - { - throw new PSQLException ("postgresql.res.badbigdec", PSQLState.NUMERIC_VALUE_OUT_OF_RANGE, s); - } - } - return null; // SQL NULL - } - - public static float toFloat(String s) throws SQLException - { - if (s != null) - { - try - { - s = s.trim(); - return Float.valueOf(s).floatValue(); - } - catch (NumberFormatException e) - { - throw new PSQLException ("postgresql.res.badfloat", PSQLState.NUMERIC_VALUE_OUT_OF_RANGE, s); - } - } - return 0; // SQL NULL - } - - public static double toDouble(String s) throws SQLException - { - if (s != null) - { - try - { - s = s.trim(); - return Double.valueOf(s).doubleValue(); - } - catch (NumberFormatException e) - { - throw new PSQLException ("postgresql.res.baddouble", PSQLState.NUMERIC_VALUE_OUT_OF_RANGE, s); - } - } - return 0; // SQL NULL - } - - public static java.sql.Date toDate(String s) throws SQLException - { - if (s == null) - return null; - // length == 10: SQL Date - // length > 10: SQL Timestamp, assumes PGDATESTYLE=ISO - try - { - s = s.trim(); - return java.sql.Date.valueOf((s.length() == 10) ? s : s.substring(0, 10)); - } - catch (NumberFormatException e) - { - throw new PSQLException("postgresql.res.baddate",PSQLState.BAD_DATETIME_FORMAT, s); - } - } - - public static Time toTime(String s, BaseResultSet resultSet, String pgDataType) throws SQLException - { - if (s == null) - return null; // SQL NULL - try - { - s = s.trim(); - if (s.length() == 8) - { - //value is a time value - return java.sql.Time.valueOf(s); - } - else if (s.indexOf(".") == 8) - { - //value is a time value with fractional seconds - java.sql.Time l_time = java.sql.Time.valueOf(s.substring(0, 8)); - String l_strMillis = s.substring(9); - if (l_strMillis.length() > 3) - l_strMillis = l_strMillis.substring(0, 3); - int l_millis = Integer.parseInt(l_strMillis); - if (l_millis < 10) - { - l_millis = l_millis * 100; - } - else if (l_millis < 100) - { - l_millis = l_millis * 10; - } - return new java.sql.Time(l_time.getTime() + l_millis); - } - else - { - //value is a timestamp - return new java.sql.Time(toTimestamp(s, resultSet, pgDataType).getTime()); - } - } - catch (NumberFormatException e) - { - throw new PSQLException("postgresql.res.badtime", PSQLState.BAD_DATETIME_FORMAT, s); - } - } - - /** - * Parse a string and return a timestamp representing its value. - * - * The driver is set to return ISO date formated strings. We modify this - * string from the ISO format to a format that Java can understand. Java - * expects timezone info as 'GMT+09:00' where as ISO gives '+09'. - * Java also expects fractional seconds to 3 places where postgres - * will give, none, 2 or 6 depending on the time and postgres version. - * From version 7.2 postgres returns fractional seconds to 6 places. - * - * According to the Timestamp documentation, fractional digits are kept - * in the nanos field of Timestamp and not in the milliseconds of Date. - * Thus, parsing for fractional digits is entirely separated from the - * rest. - * - * The method assumes that there are no more than 9 fractional - * digits given. Undefined behavior if this is not the case. - * - * @param s The ISO formated date string to parse. - * @param resultSet The ResultSet this date is part of. - * - * @return null if s is null or a timestamp of the parsed string s. - * - * @throws SQLException if there is a problem parsing s. - **/ - public static Timestamp toTimestamp(String s, BaseResultSet resultSet, String pgDataType) - throws SQLException - { - BaseResultSet rs = resultSet; - if (s == null) - return null; - - s = s.trim(); - // We must be synchronized here incase more theads access the ResultSet - // bad practice but possible. Anyhow this is to protect sbuf and - // SimpleDateFormat objects - synchronized (rs) - { - StringBuffer l_sbuf = rs.getStringBuffer(); - SimpleDateFormat df = null; - if ( Driver.logDebug ) - Driver.debug("the data from the DB is " + s); - - // If first time, create the buffer, otherwise clear it. - if (l_sbuf == null) - l_sbuf = new StringBuffer(32); - else - { - l_sbuf.setLength(0); - } - - // Copy s into sbuf for parsing. - l_sbuf.append(s); - int slen = s.length(); - - // For a Timestamp, the fractional seconds are stored in the - // nanos field. As a DateFormat is used for parsing which can - // only parse to millisecond precision and which returns a - // Date object, the fractional second parsing is completely - // separate. - int nanos = 0; - - if (slen > 19) - { - // The len of the ISO string to the second value is 19 chars. If - // greater then 19, there may be tz info and perhaps fractional - // second info which we need to change to java to read it. - - // cut the copy to second value "2001-12-07 16:29:22" - int i = 19; - l_sbuf.setLength(i); - - char c = s.charAt(i++); - if (c == '.') - { - // Found a fractional value. - final int start = i; - while (true) - { - c = s.charAt(i++); - if (!Character.isDigit(c)) - break; - if (i == slen) - { - i++; - break; - } - } - - // The range [start, i - 1) contains all fractional digits. - final int end = i - 1; - try - { - nanos = Integer.parseInt(s.substring(start, end)); - } - catch (NumberFormatException e) - { - throw new PSQLException("postgresql.unusual", PSQLState.UNEXPECTED_ERROR, e); - } - - // The nanos field stores nanoseconds. Adjust the parsed - // value to the correct magnitude. - for (int digitsToNano = 9 - (end - start); - digitsToNano > 0; --digitsToNano) - nanos *= 10; - } - - if (i < slen) - { - // prepend the GMT part and then add the remaining bit of - // the string. - l_sbuf.append(" GMT"); - l_sbuf.append(c); - l_sbuf.append(s.substring(i, slen)); - - // Lastly, if the tz part doesn't specify the :MM part then - // we add ":00" for java. - if (slen - i < 5) - l_sbuf.append(":00"); - - // we'll use this dateformat string to parse the result. - df = rs.getTimestampTZFormat(); - } - else - { - // Just found fractional seconds but no timezone. - //If timestamptz then we use GMT, else local timezone - if (pgDataType.equals("timestamptz")) - { - l_sbuf.append(" GMT"); - df = rs.getTimestampTZFormat(); - } - else - { - df = rs.getTimestampFormat(); - } - } - } - else if (slen == 19) - { - // No tz or fractional second info. - //If timestamptz then we use GMT, else local timezone - if (pgDataType.equals("timestamptz")) - { - l_sbuf.append(" GMT"); - df = rs.getTimestampTZFormat(); - } - else - { - df = rs.getTimestampFormat(); - } - } - else - { - if (slen == 8 && s.equals("infinity")) - //java doesn't have a concept of postgres's infinity - //so set to an arbitrary future date - s = "9999-01-01"; - if (slen == 9 && s.equals("-infinity")) - //java doesn't have a concept of postgres's infinity - //so set to an arbitrary old date - s = "0001-01-01"; - - // We must just have a date. This case is - // needed if this method is called on a date - // column - df = rs.getDateFormat(); - } - - try - { - // All that's left is to parse the string and return the ts. - if ( Driver.logDebug ) - Driver.debug("the data after parsing is " - + l_sbuf.toString() + " with " + nanos + " nanos"); - - Timestamp result = new Timestamp(df.parse(l_sbuf.toString()).getTime()); - result.setNanos(nanos); - return result; - } - catch (ParseException e) - { - throw new PSQLException("postgresql.res.badtimestamp", PSQLState.BAD_DATETIME_FORMAT, new Integer(e.getErrorOffset()), s); - } - } - } - - private boolean isColumnTrimmable(int columnIndex) throws SQLException - { - switch (fields[columnIndex-1].getSQLType()) - { - case Types.CHAR: - case Types.VARCHAR: - case Types.LONGVARCHAR: - case Types.BINARY: - case Types.VARBINARY: - case Types.LONGVARBINARY: - return true; - } - return false; - } - - private byte[] trimBytes(int p_columnIndex, byte[] p_bytes) throws SQLException - { - int l_maxSize = statement.getMaxFieldSize(); - //we need to trim if maxsize is set and the length is greater than maxsize and the - //type of this column is a candidate for trimming - if (l_maxSize > 0 && p_bytes.length > l_maxSize && isColumnTrimmable(p_columnIndex)) - { - byte[] l_bytes = new byte[l_maxSize]; - System.arraycopy (p_bytes, 0, l_bytes, 0, l_maxSize); - return l_bytes; - } - else - { - return p_bytes; - } - } - - private String trimString(int p_columnIndex, String p_string) throws SQLException - { - int l_maxSize = statement.getMaxFieldSize(); - //we need to trim if maxsize is set and the length is greater than maxsize and the - //type of this column is a candidate for trimming - if (l_maxSize > 0 && p_string.length() > l_maxSize && isColumnTrimmable(p_columnIndex)) - { - return p_string.substring(0,l_maxSize); - } - else - { - return p_string; - } - } - - public SimpleDateFormat getTimestampTZFormat() { - if (m_tstzFormat == null) { - m_tstzFormat = new SimpleDateFormat("yyyy-MM-dd HH:mm:ss z"); - } - return m_tstzFormat; - } - public SimpleDateFormat getTimestampFormat() { - if (m_tsFormat == null) { - m_tsFormat = new SimpleDateFormat ("yyyy-MM-dd HH:mm:ss"); - } - return m_tsFormat; - } - public SimpleDateFormat getDateFormat() { - if (m_dateFormat == null) { - m_dateFormat = new SimpleDateFormat("yyyy-MM-dd"); - } - return m_dateFormat; - } -} - diff --git a/src/interfaces/jdbc/org/postgresql/jdbc1/AbstractJdbc1ResultSetMetaData.java b/src/interfaces/jdbc/org/postgresql/jdbc1/AbstractJdbc1ResultSetMetaData.java deleted file mode 100644 index fc0d5ee33ae..00000000000 --- a/src/interfaces/jdbc/org/postgresql/jdbc1/AbstractJdbc1ResultSetMetaData.java +++ /dev/null @@ -1,462 +0,0 @@ -package org.postgresql.jdbc1; - - -import org.postgresql.core.Field; -import org.postgresql.util.PSQLException; -import org.postgresql.util.PSQLState; -import java.sql.SQLException; -import java.sql.Types; -import java.util.Vector; - -public abstract class AbstractJdbc1ResultSetMetaData -{ - - protected Vector rows; - protected Field[] fields; - - /* - * Initialise for a result with a tuple set and - * a field descriptor set - * - * @param rows the Vector of rows returned by the ResultSet - * @param fields the array of field descriptors - */ - public AbstractJdbc1ResultSetMetaData(Vector rows, Field[] fields) - { - this.rows = rows; - this.fields = fields; - } - - /* - * Whats the number of columns in the ResultSet? - * - * @return the number - * @exception SQLException if a database access error occurs - */ - public int getColumnCount() throws SQLException - { - return fields.length; - } - - /* - * Is the column automatically numbered (and thus read-only) - * I believe that PostgreSQL does not support this feature. - * - * @param column the first column is 1, the second is 2... - * @return true if so - * @exception SQLException if a database access error occurs - */ - public boolean isAutoIncrement(int column) throws SQLException - { - return false; - } - - /* - * Does a column's case matter? ASSUMPTION: Any field that is - * not obviously case insensitive is assumed to be case sensitive - * - * @param column the first column is 1, the second is 2... - * @return true if so - * @exception SQLException if a database access error occurs - */ - public boolean isCaseSensitive(int column) throws SQLException - { - int sql_type = getField(column).getSQLType(); - - switch (sql_type) - { - case Types.SMALLINT: - case Types.INTEGER: - case Types.FLOAT: - case Types.REAL: - case Types.DOUBLE: - case Types.DATE: - case Types.TIME: - case Types.TIMESTAMP: - return false; - default: - return true; - } - } - - /* - * Can the column be used in a WHERE clause? Basically for - * this, I split the functions into two types: recognised - * types (which are always useable), and OTHER types (which - * may or may not be useable). The OTHER types, for now, I - * will assume they are useable. We should really query the - * catalog to see if they are useable. - * - * @param column the first column is 1, the second is 2... - * @return true if they can be used in a WHERE clause - * @exception SQLException if a database access error occurs - */ - public boolean isSearchable(int column) throws SQLException - { - int sql_type = getField(column).getSQLType(); - - // This switch is pointless, I know - but it is a set-up - // for further expansion. - switch (sql_type) - { - case Types.OTHER: - return true; - default: - return true; - } - } - - /* - * Is the column a cash value? 6.1 introduced the cash/money - * type, which haven't been incorporated as of 970414, so I - * just check the type name for both 'cash' and 'money' - * - * @param column the first column is 1, the second is 2... - * @return true if its a cash column - * @exception SQLException if a database access error occurs - */ - public boolean isCurrency(int column) throws SQLException - { - String type_name = getField(column).getPGType(); - - return type_name.equals("cash") || type_name.equals("money"); - } - - /* - * Indicates the nullability of values in the designated column. - * - * @param column the first column is 1, the second is 2... - * @return one of the columnNullable values - * @exception SQLException if a database access error occurs - */ - public int isNullable(int column) throws SQLException - { - /* - * TODO This needs a real implementation, taking into account columns - * defined with NOT NULL or PRIMARY KEY, CHECK constraints, views, - * functions etc. - */ - return java.sql.ResultSetMetaData.columnNullableUnknown; - } - - /* - * Is the column a signed number? In PostgreSQL, all numbers - * are signed, so this is trivial. However, strings are not - * signed (duh!) - * - * @param column the first column is 1, the second is 2... - * @return true if so - * @exception SQLException if a database access error occurs - */ - public boolean isSigned(int column) throws SQLException - { - int sql_type = getField(column).getSQLType(); - - switch (sql_type) - { - case Types.SMALLINT: - case Types.INTEGER: - case Types.FLOAT: - case Types.REAL: - case Types.DOUBLE: - return true; - case Types.DATE: - case Types.TIME: - case Types.TIMESTAMP: - return false; // I don't know about these? - default: - return false; - } - } - - /* - * What is the column's normal maximum width in characters? - * - * @param column the first column is 1, the second is 2, etc. - * @return the maximum width - * @exception SQLException if a database access error occurs - */ - public int getColumnDisplaySize(int column) throws SQLException - { - Field f = getField(column); - String type_name = f.getPGType(); - int typmod = f.getMod(); - - // I looked at other JDBC implementations and couldn't find a consistent - // interpretation of the "display size" for numeric values, so this is our's - // FIXME: currently, only types with a SQL92 or SQL3 pendant are implemented - [email protected] - - // fixed length data types - if (type_name.equals( "int2" )) - return 6; // -32768 to +32768 (5 digits and a sign) - if (type_name.equals( "int4" ) - || type_name.equals( "oid" )) - return 11; // -2147483648 to +2147483647 - if (type_name.equals( "int8" )) - return 20; // -9223372036854775808 to +9223372036854775807 - if (type_name.equals( "money" )) - return 12; // MONEY = DECIMAL(9,2) - if (type_name.equals( "float4" )) - return 11; // i checked it out ans wasn't able to produce more than 11 digits - if (type_name.equals( "float8" )) - return 20; // dito, 20 - if (type_name.equals( "char" )) - return 1; - if (type_name.equals( "bool" )) - return 1; - if (type_name.equals( "date" )) - return 14; // "01/01/4713 BC" - "31/12/32767 AD" - if (type_name.equals( "time" )) - return 8; // 00:00:00-23:59:59 - if (type_name.equals( "timestamp" )) - return 22; // hhmmm ... the output looks like this: 1999-08-03 22:22:08+02 - - // variable length fields - typmod -= 4; - if (type_name.equals( "bpchar" ) - || type_name.equals( "varchar" )) - return typmod; // VARHDRSZ=sizeof(int32)=4 - if (type_name.equals( "numeric" )) - return ( (typmod >> 16) & 0xffff ) - + 1 + ( typmod & 0xffff ); // DECIMAL(p,s) = (p digits).(s digits) - - // if we don't know better - return f.getLength(); - } - - /* - * What is the suggested column title for use in printouts and - * displays? We suggest the ColumnName! - * - * @param column the first column is 1, the second is 2, etc. - * @return the column label - * @exception SQLException if a database access error occurs - */ - public String getColumnLabel(int column) throws SQLException - { - return getColumnName(column); - } - - /* - * What's a column's name? - * - * @param column the first column is 1, the second is 2, etc. - * @return the column name - * @exception SQLException if a database access error occurs - */ - public String getColumnName(int column) throws SQLException - { - Field f = getField(column); - if (f != null) - return f.getName(); - return "field" + column; - } - - /* - * What is a column's table's schema? This relies on us knowing - * the table name....which I don't know how to do as yet. The - * JDBC specification allows us to return "" if this is not - * applicable. - * - * @param column the first column is 1, the second is 2... - * @return the Schema - * @exception SQLException if a database access error occurs - */ - public String getSchemaName(int column) throws SQLException - { - return ""; - } - - /* - * What is a column's number of decimal digits. - * - * @param column the first column is 1, the second is 2... - * @return the precision - * @exception SQLException if a database access error occurs - */ - public int getPrecision(int column) throws SQLException - { - int sql_type = getField(column).getSQLType(); - - switch (sql_type) - { - case Types.SMALLINT: - return 5; - case Types.INTEGER: - return 10; - case Types.REAL: - return 8; - case Types.FLOAT: - return 16; - case Types.DOUBLE: - return 16; - case Types.VARCHAR: - return 0; - case Types.NUMERIC: - Field f = getField(column); - if (f != null) - return ((0xFFFF0000)&f.getMod()) >> 16; - else - return 0; - default: - return 0; - } - } - - /* - * What is a column's number of digits to the right of the - * decimal point? - * - * @param column the first column is 1, the second is 2... - * @return the scale - * @exception SQLException if a database access error occurs - */ - public int getScale(int column) throws SQLException - { - int sql_type = getField(column).getSQLType(); - - switch (sql_type) - { - case Types.SMALLINT: - return 0; - case Types.INTEGER: - return 0; - case Types.REAL: - return 8; - case Types.FLOAT: - return 16; - case Types.DOUBLE: - return 16; - case Types.VARCHAR: - return 0; - case Types.NUMERIC: - Field f = getField(column); - if (f != null) - return (((0x0000FFFF)&f.getMod()) - 4); - else - return 0; - default: - return 0; - } - } - - /* - * Whats a column's table's name? How do I find this out? Both - * getSchemaName() and getCatalogName() rely on knowing the table - * Name, so we need this before we can work on them. - * - * @param column the first column is 1, the second is 2... - * @return column name, or "" if not applicable - * @exception SQLException if a database access error occurs - */ - public String getTableName(int column) throws SQLException - { - return ""; - } - - /* - * What's a column's table's catalog name? As with getSchemaName(), - * we can say that if getTableName() returns n/a, then we can too - - * otherwise, we need to work on it. - * - * @param column the first column is 1, the second is 2... - * @return catalog name, or "" if not applicable - * @exception SQLException if a database access error occurs - */ - public String getCatalogName(int column) throws SQLException - { - return ""; - } - - /* - * What is a column's SQL Type? (java.sql.Type int) - * - * @param column the first column is 1, the second is 2, etc. - * @return the java.sql.Type value - * @exception SQLException if a database access error occurs - * @see org.postgresql.Field#getSQLType - * @see java.sql.Types - */ - public int getColumnType(int column) throws SQLException - { - return getField(column).getSQLType(); - } - - /* - * Whats is the column's data source specific type name? - * - * @param column the first column is 1, the second is 2, etc. - * @return the type name - * @exception SQLException if a database access error occurs - */ - public String getColumnTypeName(int column) throws SQLException - { - return getField(column).getPGType(); - } - - /* - * Is the column definitely not writable? In reality, we would - * have to check the GRANT/REVOKE stuff for this to be effective, - * and I haven't really looked into that yet, so this will get - * re-visited. - * - * @param column the first column is 1, the second is 2, etc. - * @return true if so - * @exception SQLException if a database access error occurs - */ - public boolean isReadOnly(int column) throws SQLException - { - return false; - } - - /* - * Is it possible for a write on the column to succeed? Again, we - * would in reality have to check the GRANT/REVOKE stuff, which - * I haven't worked with as yet. However, if it isn't ReadOnly, then - * it is obviously writable. - * - * @param column the first column is 1, the second is 2, etc. - * @return true if so - * @exception SQLException if a database access error occurs - */ - public boolean isWritable(int column) throws SQLException - { - return !isReadOnly(column); - } - - /* - * Will a write on this column definately succeed? Hmmm...this - * is a bad one, since the two preceding functions have not been - * really defined. I cannot tell is the short answer. I thus - * return isWritable() just to give us an idea. - * - * @param column the first column is 1, the second is 2, etc.. - * @return true if so - * @exception SQLException if a database access error occurs - */ - public boolean isDefinitelyWritable(int column) throws SQLException - { - return false; - } - - // ******************************************************** - // END OF PUBLIC INTERFACE - // ******************************************************** - - /* - * For several routines in this package, we need to convert - * a columnIndex into a Field[] descriptor. Rather than do - * the same code several times, here it is. - * - * @param columnIndex the first column is 1, the second is 2... - * @return the Field description - * @exception SQLException if a database access error occurs - */ - private Field getField(int columnIndex) throws SQLException - { - if (columnIndex < 1 || columnIndex > fields.length) - throw new PSQLException("postgresql.res.colrange", PSQLState.INVALID_PARAMETER_VALUE); - return fields[columnIndex - 1]; - } -} - diff --git a/src/interfaces/jdbc/org/postgresql/jdbc1/AbstractJdbc1Statement.java b/src/interfaces/jdbc/org/postgresql/jdbc1/AbstractJdbc1Statement.java deleted file mode 100644 index c8644f42ac9..00000000000 --- a/src/interfaces/jdbc/org/postgresql/jdbc1/AbstractJdbc1Statement.java +++ /dev/null @@ -1,2309 +0,0 @@ -package org.postgresql.jdbc1; - -import org.postgresql.core.BaseConnection; -import org.postgresql.core.BaseResultSet; -import org.postgresql.core.BaseStatement; -import org.postgresql.core.Field; -import org.postgresql.core.QueryExecutor; -import org.postgresql.largeobject.LargeObject; -import org.postgresql.largeobject.LargeObjectManager; -import org.postgresql.util.PGbytea; -import org.postgresql.util.PGobject; -import org.postgresql.util.PSQLException; -import org.postgresql.util.PSQLState; -import java.io.IOException; -import java.io.InputStream; -import java.io.InputStreamReader; -import java.io.OutputStream; -import java.io.UnsupportedEncodingException; -import java.math.BigDecimal; -import java.sql.CallableStatement; -import java.sql.ResultSet; -import java.sql.SQLException; -import java.sql.SQLWarning; -import java.sql.Time; -import java.sql.Timestamp; -import java.sql.Types; -import java.util.Vector; - -/* $PostgreSQL: pgsql/src/interfaces/jdbc/org/postgresql/jdbc1/AbstractJdbc1Statement.java,v 1.44 2003/12/12 18:36:19 davec Exp $ - * This class defines methods of the jdbc1 specification. This class is - * extended by org.postgresql.jdbc2.AbstractJdbc2Statement which adds the jdbc2 - * methods. The real Statement class (for jdbc1) is org.postgresql.jdbc1.Jdbc1Statement - */ -public abstract class AbstractJdbc1Statement implements BaseStatement -{ - // The connection who created us - protected BaseConnection connection; - - /** The warnings chain. */ - protected SQLWarning warnings = null; - - /** Maximum number of rows to return, 0 = unlimited */ - protected int maxrows = 0; - - /** Number of rows to get in a batch. */ - protected int fetchSize = 0; - - /** Timeout (in seconds) for a query (not used) */ - protected int timeout = 0; - - protected boolean replaceProcessingEnabled = true; - - /** The current results */ - protected BaseResultSet result = null; - - // Static variables for parsing SQL when replaceProcessing is true. - private static final short IN_SQLCODE = 0; - private static final short IN_STRING = 1; - private static final short BACKSLASH = 2; - private static final short ESC_TIMEDATE = 3; - - // Some performance caches - private StringBuffer sbuf = new StringBuffer(32); - - protected String[] m_sqlFragments; // Query fragments. - private String[] m_executeSqlFragments; // EXECUTE(...) if useServerPrepare - protected Object[] m_binds = new Object[0]; // Parameter values - - protected String[] m_bindTypes = new String[0]; // Parameter types, for PREPARE(...) - protected String m_statementName = null; // Allocated PREPARE statement name for server-prepared statements - protected String m_cursorName = null; // Allocated DECLARE cursor name for cursor-based fetch - - // Constants for allowXXX and m_isSingleStatement vars, below. - // The idea is to defer the cost of examining the query until we really need to know, - // but don't reexamine it every time thereafter. - - private static final short UNKNOWN = 0; // Don't know yet, examine the query. - private static final short NO = 1; // Don't use feature - private static final short YES = 2; // Do use feature - - private short m_isSingleDML = UNKNOWN; // Is the query a single SELECT/UPDATE/INSERT/DELETE? - private short m_isSingleSelect = UNKNOWN; // Is the query a single SELECT? - private short m_isSingleStatement = UNKNOWN; // Is the query a single statement? - - private boolean m_useServerPrepare = false; - - // m_preparedCount is used for naming of auto-cursors and must - // be synchronized so that multiple threads using the same - // connection don't stomp over each others cursors. - private static int m_preparedCount = 1; - private synchronized static int next_preparedCount() - { - return m_preparedCount++; - } - - //Used by the callablestatement style methods - private static final String JDBC_SYNTAX = "{[? =] call <some_function> ([? [,?]*]) }"; - private static final String RESULT_ALIAS = "result"; - private String originalSql = ""; - private boolean isFunction; - // functionReturnType contains the user supplied value to check - // testReturn contains a modified version to make it easier to - // check the getXXX methods.. - private int functionReturnType; - private int testReturn; - // returnTypeSet is true when a proper call to registerOutParameter has been made - private boolean returnTypeSet; - protected Object callResult; - protected int maxfieldSize = 0; - - public abstract BaseResultSet createResultSet(Field[] fields, Vector tuples, String status, int updateCount, long insertOID, boolean binaryCursor) throws SQLException; - - public AbstractJdbc1Statement (BaseConnection connection) - { - this.connection = connection; - } - - public AbstractJdbc1Statement (BaseConnection connection, String p_sql) throws SQLException - { - this.connection = connection; - parseSqlStmt(p_sql); // this allows Callable stmt to override - } - - public BaseConnection getPGConnection() { - return connection; - } - - public String getFetchingCursorName() { - return m_cursorName; - } - - public int getFetchSize() { - return fetchSize; - } - - protected void parseSqlStmt (String p_sql) throws SQLException - { - String l_sql = p_sql; - - l_sql = replaceProcessing(l_sql); - - if (this instanceof CallableStatement) - { - l_sql = modifyJdbcCall(l_sql); - } - - Vector v = new Vector(); - boolean inQuotes = false; - int lastParmEnd = 0, i; - - m_isSingleSelect = m_isSingleDML = UNKNOWN; - m_isSingleStatement = YES; - - for (i = 0; i < l_sql.length(); ++i) - { - int c = l_sql.charAt(i); - - if (c == '\'') - inQuotes = !inQuotes; - if (c == '?' && !inQuotes) - { - v.addElement(l_sql.substring (lastParmEnd, i)); - lastParmEnd = i + 1; - } - if (c == ';' && !inQuotes) - m_isSingleStatement = m_isSingleSelect = m_isSingleDML = NO; - } - v.addElement(l_sql.substring (lastParmEnd, l_sql.length())); - - m_sqlFragments = new String[v.size()]; - m_binds = new Object[v.size() - 1]; - m_bindTypes = new String[v.size() - 1]; - - for (i = 0 ; i < m_sqlFragments.length; ++i) - m_sqlFragments[i] = (String)v.elementAt(i); - - } - - /* - * Deallocate resources allocated for the current query - * in preparation for replacing it with a new query. - */ - private void deallocateQuery() - { - //If we have already created a server prepared statement, we need - //to deallocate the existing one - if (m_statementName != null) - { - try - { - connection.execSQL("DEALLOCATE " + m_statementName); - } - catch (Exception e) - { - } - } - - m_statementName = null; - m_cursorName = null; // automatically closed at end of txn anyway - m_executeSqlFragments = null; - m_isSingleStatement = m_isSingleSelect = m_isSingleDML = UNKNOWN; - } - - /* - * Execute a SQL statement that retruns a single ResultSet - * - * @param sql typically a static SQL SELECT statement - * @return a ResulSet that contains the data produced by the query - * @exception SQLException if a database access error occurs - */ - public java.sql.ResultSet executeQuery(String p_sql) throws SQLException - { - deallocateQuery(); - - String l_sql = replaceProcessing(p_sql); - m_sqlFragments = new String[] {l_sql}; - m_binds = new Object[0]; - - return executeQuery(); - } - - /* - * A Prepared SQL query is executed and its ResultSet is returned - * - * @return a ResultSet that contains the data produced by the - * * query - never null - * @exception SQLException if a database access error occurs - */ - public java.sql.ResultSet executeQuery() throws SQLException - { - this.execute(); - - while (result != null && !result.reallyResultSet()) - result = (BaseResultSet) result.getNext(); - if (result == null) - throw new PSQLException("postgresql.stat.noresult", PSQLState.NO_DATA); - return (ResultSet) result; - } - - /* - * Execute a SQL INSERT, UPDATE or DELETE statement. In addition - * SQL statements that return nothing such as SQL DDL statements - * can be executed - * - * @param sql a SQL statement - * @return either a row count, or 0 for SQL commands - * @exception SQLException if a database access error occurs - */ - public int executeUpdate(String p_sql) throws SQLException - { - deallocateQuery(); - - String l_sql = replaceProcessing(p_sql); - m_sqlFragments = new String[] {l_sql}; - m_binds = new Object[0]; - - return executeUpdate(); - } - - /* - * Execute a SQL INSERT, UPDATE or DELETE statement. In addition, - * SQL statements that return nothing such as SQL DDL statements can - * be executed. - * - * @return either the row count for INSERT, UPDATE or DELETE; or - * * 0 for SQL statements that return nothing. - * @exception SQLException if a database access error occurs - */ - public int executeUpdate() throws SQLException - { - this.execute(); - if (result.reallyResultSet()) - throw new PSQLException("postgresql.stat.result"); - return this.getUpdateCount(); - } - - /* - * Execute a SQL statement that may return multiple results. We - * don't have to worry about this since we do not support multiple - * ResultSets. You can use getResultSet or getUpdateCount to - * retrieve the result. - * - * @param sql any SQL statement - * @return true if the next result is a ResulSet, false if it is - * an update count or there are no more results - * @exception SQLException if a database access error occurs - */ - public boolean execute(String p_sql) throws SQLException - { - deallocateQuery(); - - String l_sql = replaceProcessing(p_sql); - m_sqlFragments = new String[] {l_sql}; - m_binds = new Object[0]; - - return execute(); - } - - /* - * Check if the current query is a single statement. - */ - private boolean isSingleStatement() - { - if (m_isSingleStatement != UNKNOWN) - return m_isSingleStatement == YES; - - // Crude detection of multiple statements. This could be - // improved by parsing the whole query for quotes, but is - // it worth it given that the only queries that get here are - // unparameterized queries? - - for (int i = 0; i < m_sqlFragments.length; ++i) { // a bit redundant, but .. - if (m_sqlFragments[i].indexOf(';') != -1) { - m_isSingleStatement = NO; - return false; - } - } - - m_isSingleStatement = YES; - return true; - } - - /* - * Helper for isSingleSelect() and isSingleDML(): computes values - * of m_isSingleDML and m_isSingleSelect. - */ - private void analyzeStatementType() - { - if (!isSingleStatement()) { - m_isSingleSelect = m_isSingleDML = NO; - return; - } - - String compare = m_sqlFragments[0].trim().toLowerCase(); - if (compare.startsWith("select")) { - m_isSingleSelect = m_isSingleDML = YES; - return; - } - - m_isSingleSelect = NO; - - if (!compare.startsWith("update") && - !compare.startsWith("delete") && - !compare.startsWith("insert")) { - m_isSingleDML = NO; - return; - } - - m_isSingleDML = YES; - } - - /* - * Check if the current query is a single SELECT. - */ - private boolean isSingleSelect() - { - if (m_isSingleSelect == UNKNOWN) - analyzeStatementType(); - - return m_isSingleSelect == YES; - } - - /* - * Check if the current query is a single SELECT/UPDATE/INSERT/DELETE. - */ - private boolean isSingleDML() - { - if (m_isSingleDML == UNKNOWN) - analyzeStatementType(); - - return m_isSingleDML == YES; - } - - /* - * Return the query fragments to use for a server-prepared statement. - * The first query executed will include a PREPARE and EXECUTE; - * subsequent queries will just be an EXECUTE. - */ - private String[] transformToServerPrepare() { - if (m_statementName != null) - return m_executeSqlFragments; - - // First time through. - m_statementName = "JDBC_STATEMENT_" + m_preparedCount++; - - // Set up m_executeSqlFragments - m_executeSqlFragments = new String[m_sqlFragments.length]; - m_executeSqlFragments[0] = "EXECUTE " + m_statementName; - if (m_sqlFragments.length > 1) { - m_executeSqlFragments[0] += "("; - for (int i = 1; i < m_bindTypes.length; i++) - m_executeSqlFragments[i] = ", "; - m_executeSqlFragments[m_bindTypes.length] = ")"; - } - - // Set up the PREPARE. - String[] prepareSqlFragments = new String[m_sqlFragments.length]; - System.arraycopy(m_sqlFragments, 0, prepareSqlFragments, 0, m_sqlFragments.length); - - synchronized (sbuf) { - sbuf.setLength(0); - sbuf.append("PREPARE "); - sbuf.append(m_statementName); - if (m_sqlFragments.length > 1) { - sbuf.append("("); - for (int i = 0; i < m_bindTypes.length; i++) { - if (i != 0) sbuf.append(", "); - sbuf.append(m_bindTypes[i]); - } - sbuf.append(")"); - } - sbuf.append(" AS "); - sbuf.append(m_sqlFragments[0]); - for (int i = 1; i < m_sqlFragments.length; i++) { - sbuf.append(" $"); - sbuf.append(i); - sbuf.append(" "); - sbuf.append(m_sqlFragments[i]); - } - sbuf.append("; "); - sbuf.append(m_executeSqlFragments[0]); - - prepareSqlFragments[0] = sbuf.toString(); - } - - System.arraycopy(m_executeSqlFragments, 1, prepareSqlFragments, 1, prepareSqlFragments.length - 1); - return prepareSqlFragments; - } - - /* - * Return the current query transformed into a cursor-based statement. - * This uses a new cursor on each query. - */ - private String[] transformToCursorFetch() - { - - // Pinch the prepared count for our own nefarious purposes. - m_cursorName = "JDBC_CURS_" + m_preparedCount++; - - // Create a cursor declaration and initial fetch statement from the original query. - int len = m_sqlFragments.length; - String[] cursorBasedSql = new String[len]; - System.arraycopy(m_sqlFragments, 0, cursorBasedSql, 0, len); - cursorBasedSql[0] = "DECLARE " + m_cursorName + " CURSOR FOR " + cursorBasedSql[0]; - cursorBasedSql[len-1] += "; FETCH FORWARD " + fetchSize + " FROM " + m_cursorName; - - // Make the cursor based query the one that will be used. - if (org.postgresql.Driver.logDebug) - org.postgresql.Driver.debug("using cursor based sql with cursor name " + m_cursorName); - - return cursorBasedSql; - } - - /** - * Do transformations to a query for server-side prepare or setFetchSize() cursor - * work. - * @return the query fragments to execute - */ - private String[] getQueryFragments() - { - // nb: isSingleXXX() are relatively expensive, avoid calling them unless we must. - - // We check the "mutable" bits of these conditions (which may change without - // a new query being created) here; isSingleXXX() only concern themselves with - // the query structure itself. - - // We prefer cursor-based-fetch over server-side-prepare here. - // Eventually a v3 implementation should let us do both at once. - if (fetchSize > 0 && !connection.getAutoCommit() && isSingleSelect()) - return transformToCursorFetch(); - - if (isUseServerPrepare() && isSingleDML()) - return transformToServerPrepare(); - - // Not server-prepare or cursor-fetch, just return a plain query. - return m_sqlFragments; - } - - /* - * Some prepared statements return multiple results; the execute method - * handles these complex statements as well as the simpler form of - * statements handled by executeQuery and executeUpdate - * - * @return true if the next result is a ResultSet; false if it is an - * update count or there are no more results - * @exception SQLException if a database access error occurs - */ - public boolean execute() throws SQLException - { - if (isFunction && !returnTypeSet) - throw new PSQLException("postgresql.call.noreturntype", PSQLState.STATEMENT_NOT_ALLOWED_IN_FUNCTION_CALL); - if (isFunction) - { // set entry 1 to dummy entry.. - m_binds[0] = ""; // dummy entry which ensured that no one overrode - m_bindTypes[0] = PG_TEXT; - // and calls to setXXX (2,..) really went to first arg in a function call.. - } - - // New in 7.1, if we have a previous resultset then force it to close - // This brings us nearer to compliance, and helps memory management. - // Internal stuff will call ExecSQL directly, bypassing this. - - if (result != null) - { - java.sql.ResultSet rs = getResultSet(); - if (rs != null) - rs.close(); - } - - // Get the actual query fragments to run (might be a transformed version of - // the original fragments) - String[] fragments = getQueryFragments(); - - // New in 7.1, pass Statement so that ExecSQL can customise to it - result = QueryExecutor.execute(fragments, - m_binds, - this); - - //If we are executing a callable statement function set the return data - if (isFunction) - { - if (!result.reallyResultSet()) - throw new PSQLException("postgresql.call.noreturnval", PSQLState.NO_DATA); - if (!result.next ()) - throw new PSQLException ("postgresql.call.noreturnval", PSQLState.NO_DATA); - callResult = result.getObject(1); - int columnType = result.getMetaData().getColumnType(1); - if (columnType != functionReturnType) - throw new PSQLException ("postgresql.call.wrongrtntype", PSQLState.DATA_TYPE_MISMATCH, - new Object[]{ - "java.sql.Types=" + columnType, "java.sql.Types=" + functionReturnType }); - result.close (); - return true; - } - else - { - return (result != null && result.reallyResultSet()); - } - } - - /* - * setCursorName defines the SQL cursor name that will be used by - * subsequent execute methods. This name can then be used in SQL - * positioned update/delete statements to identify the current row - * in the ResultSet generated by this statement. If a database - * doesn't support positioned update/delete, this method is a - * no-op. - * - * <p><B>Note:</B> By definition, positioned update/delete execution - * must be done by a different Statement than the one which - * generated the ResultSet being used for positioning. Also, cursor - * names must be unique within a Connection. - * - * <p>We throw an additional constriction. There can only be one - * cursor active at any one time. - * - * @param name the new cursor name - * @exception SQLException if a database access error occurs - */ - public void setCursorName(String name) throws SQLException - { - connection.setCursorName(name); - } - - - /* - * getUpdateCount returns the current result as an update count, - * if the result is a ResultSet or there are no more results, -1 - * is returned. It should only be called once per result. - * - * @return the current result as an update count. - * @exception SQLException if a database access error occurs - */ - public int getUpdateCount() throws SQLException - { - if (result == null) - return -1; - if (isFunction) - return 1; - if (result.reallyResultSet()) - return -1; - return result.getResultCount(); - } - - /* - * getMoreResults moves to a Statement's next result. If it returns - * true, this result is a ResulSet. - * - * @return true if the next ResultSet is valid - * @exception SQLException if a database access error occurs - */ - public boolean getMoreResults() throws SQLException - { - result = (BaseResultSet) result.getNext(); - return (result != null && result.reallyResultSet()); - } - - - - /* - * Returns the status message from the current Result.<p> - * This is used internally by the driver. - * - * @return status message from backend - */ - public String getResultStatusString() - { - if (result == null) - return null; - return result.getStatusString(); - } - - /* - * The maxRows limit is set to limit the number of rows that - * any ResultSet can contain. If the limit is exceeded, the - * excess rows are silently dropped. - * - * @return the current maximum row limit; zero means unlimited - * @exception SQLException if a database access error occurs - */ - public int getMaxRows() throws SQLException - { - return maxrows; - } - - /* - * Set the maximum number of rows - * - * @param max the new max rows limit; zero means unlimited - * @exception SQLException if a database access error occurs - * @see getMaxRows - */ - public void setMaxRows(int max) throws SQLException - { - if (max<0) throw new PSQLException("postgresql.input.rows.gt0"); - maxrows = max; - } - - /* - * If escape scanning is on (the default), the driver will do escape - * substitution before sending the SQL to the database. - * - * @param enable true to enable; false to disable - * @exception SQLException if a database access error occurs - */ - public void setEscapeProcessing(boolean enable) throws SQLException - { - replaceProcessingEnabled = enable; - } - - /* - * The queryTimeout limit is the number of seconds the driver - * will wait for a Statement to execute. If the limit is - * exceeded, a SQLException is thrown. - * - * @return the current query timeout limit in seconds; 0 = unlimited - * @exception SQLException if a database access error occurs - */ - public int getQueryTimeout() throws SQLException - { - return timeout; - } - - /* - * Sets the queryTimeout limit - * - * @param seconds - the new query timeout limit in seconds - * @exception SQLException if a database access error occurs - */ - public void setQueryTimeout(int seconds) throws SQLException - { - if (seconds<0) throw new PSQLException("postgresql.input.query.gt0"); - timeout = seconds; - } - - /** - * This adds a warning to the warning chain. - * @param msg message to add - */ - public void addWarning(String msg) - { - if (warnings != null) - warnings.setNextWarning(new SQLWarning(msg)); - else - warnings = new SQLWarning(msg); - } - - /* - * The first warning reported by calls on this Statement is - * returned. A Statement's execute methods clear its SQLWarning - * chain. Subsequent Statement warnings will be chained to this - * SQLWarning. - * - * <p>The Warning chain is automatically cleared each time a statement - * is (re)executed. - * - * <p><B>Note:</B> If you are processing a ResultSet then any warnings - * associated with ResultSet reads will be chained on the ResultSet - * object. - * - * @return the first SQLWarning on null - * @exception SQLException if a database access error occurs - */ - public SQLWarning getWarnings() throws SQLException - { - return warnings; - } - - /* - * The maxFieldSize limit (in bytes) is the maximum amount of - * data returned for any column value; it only applies to - * BINARY, VARBINARY, LONGVARBINARY, CHAR, VARCHAR and LONGVARCHAR - * columns. If the limit is exceeded, the excess data is silently - * discarded. - * - * @return the current max column size limit; zero means unlimited - * @exception SQLException if a database access error occurs - */ - public int getMaxFieldSize() throws SQLException - { - return maxfieldSize; - } - - /* - * Sets the maxFieldSize - * - * @param max the new max column size limit; zero means unlimited - * @exception SQLException if a database access error occurs - */ - public void setMaxFieldSize(int max) throws SQLException - { - if (max < 0) throw new PSQLException("postgresql.input.field.gt0"); - maxfieldSize = max; - } - - /* - * After this call, getWarnings returns null until a new warning - * is reported for this Statement. - * - * @exception SQLException if a database access error occurs - */ - public void clearWarnings() throws SQLException - { - warnings = null; - } - - /* - * Cancel can be used by one thread to cancel a statement that - * is being executed by another thread. - * <p> - * Not implemented, this method is a no-op. - * - * @exception SQLException only because thats the spec. - */ - public void cancel() throws SQLException - { - throw new PSQLException("postgresql.unimplemented", PSQLState.NOT_IMPLEMENTED); - } - - /* - * getResultSet returns the current result as a ResultSet. It - * should only be called once per result. - * - * @return the current result set; null if there are no more - * @exception SQLException if a database access error occurs (why?) - */ - public java.sql.ResultSet getResultSet() throws SQLException - { - if (result != null && result.reallyResultSet()) - return (ResultSet) result; - return null; - } - - /* - * In many cases, it is desirable to immediately release a - * Statement's database and JDBC resources instead of waiting - * for this to happen when it is automatically closed. The - * close method provides this immediate release. - * - * <p><B>Note:</B> A Statement is automatically closed when it is - * garbage collected. When a Statement is closed, its current - * ResultSet, if one exists, is also closed. - * - * @exception SQLException if a database access error occurs (why?) - */ - public void close() throws SQLException - { - // Force the ResultSet to close - java.sql.ResultSet rs = getResultSet(); - if (rs != null) - rs.close(); - - deallocateQuery(); - - // Disasociate it from us (For Garbage Collection) - result = null; - } - - /** - * This finalizer ensures that statements that have allocated server-side - * resources free them when they become unreferenced. - */ - protected void finalize() { - try { close(); } - catch (SQLException e) {} - } - - /* - * Filter the SQL string of Java SQL Escape clauses. - * - * Currently implemented Escape clauses are those mentioned in 11.3 - * in the specification. Basically we look through the sql string for - * {d xxx}, {t xxx} or {ts xxx} in non-string sql code. When we find - * them, we just strip the escape part leaving only the xxx part. - * So, something like "select * from x where d={d '2001-10-09'}" would - * return "select * from x where d= '2001-10-09'". - */ - protected String replaceProcessing(String p_sql) - { - if (replaceProcessingEnabled) - { - // Since escape codes can only appear in SQL CODE, we keep track - // of if we enter a string or not. - StringBuffer newsql = new StringBuffer(p_sql.length()); - short state = IN_SQLCODE; - - int i = -1; - int len = p_sql.length(); - while (++i < len) - { - char c = p_sql.charAt(i); - switch (state) - { - case IN_SQLCODE: - if (c == '\'') // start of a string? - state = IN_STRING; - else if (c == '{') // start of an escape code? - if (i + 1 < len) - { - char next = p_sql.charAt(i + 1); - if (next == 'd') - { - state = ESC_TIMEDATE; - i++; - break; - } - else if (next == 't') - { - state = ESC_TIMEDATE; - i += (i + 2 < len && p_sql.charAt(i + 2) == 's') ? 2 : 1; - break; - } - } - newsql.append(c); - break; - - case IN_STRING: - if (c == '\'') // end of string? - state = IN_SQLCODE; - else if (c == '\\') // a backslash? - state = BACKSLASH; - - newsql.append(c); - break; - - case BACKSLASH: - state = IN_STRING; - - newsql.append(c); - break; - - case ESC_TIMEDATE: - if (c == '}') - state = IN_SQLCODE; // end of escape code. - else - newsql.append(c); - break; - } // end switch - } - - return newsql.toString(); - } - else - { - return p_sql; - } - } - - /* - * - * The following methods are postgres extensions and are defined - * in the interface BaseStatement - * - */ - - /* - * Returns the Last inserted/updated oid. Deprecated in 7.2 because - * range of OID values is greater than a java signed int. - * @deprecated Replaced by getLastOID in 7.2 - */ - public int getInsertedOID() throws SQLException - { - if (result == null) - return 0; - return (int) result.getLastOID(); - } - - /* - * Returns the Last inserted/updated oid. - * @return OID of last insert - * @since 7.2 - */ - public long getLastOID() throws SQLException - { - if (result == null) - return 0; - return result.getLastOID(); - } - - /* - * Set a parameter to SQL NULL - * - * <p><B>Note:</B> You must specify the parameters SQL type (although - * PostgreSQL ignores it) - * - * @param parameterIndex the first parameter is 1, etc... - * @param sqlType the SQL type code defined in java.sql.Types - * @exception SQLException if a database access error occurs - */ - public void setNull(int parameterIndex, int sqlType) throws SQLException - { - String l_pgType; - switch (sqlType) - { - case Types.INTEGER: - l_pgType = PG_INTEGER; - break; - case Types.TINYINT: - case Types.SMALLINT: - l_pgType = PG_INT2; - break; - case Types.BIGINT: - l_pgType = PG_INT8; - break; - case Types.REAL: - case Types.FLOAT: - l_pgType = PG_FLOAT; - break; - case Types.DOUBLE: - l_pgType = PG_DOUBLE; - break; - case Types.DECIMAL: - case Types.NUMERIC: - l_pgType = PG_NUMERIC; - break; - case Types.CHAR: - case Types.VARCHAR: - case Types.LONGVARCHAR: - l_pgType = PG_TEXT; - break; - case Types.DATE: - l_pgType = PG_DATE; - break; - case Types.TIME: - l_pgType = PG_TIME; - break; - case Types.TIMESTAMP: - l_pgType = PG_TIMESTAMPTZ; - break; - case Types.BIT: - l_pgType = PG_BOOLEAN; - break; - case Types.BINARY: - case Types.VARBINARY: - case Types.LONGVARBINARY: - l_pgType = PG_BYTEA; - break; - case Types.OTHER: - l_pgType = PG_TEXT; - break; - default: - l_pgType = PG_TEXT; - } - bind(parameterIndex, "null", l_pgType); - } - - /* - * Set a parameter to a Java boolean value. The driver converts this - * to a SQL BIT value when it sends it to the database. - * - * @param parameterIndex the first parameter is 1... - * @param x the parameter value - * @exception SQLException if a database access error occurs - */ - public void setBoolean(int parameterIndex, boolean x) throws SQLException - { - bind(parameterIndex, x ? "'1'" : "'0'", PG_BOOLEAN); - } - - /* - * Set a parameter to a Java byte value. The driver converts this to - * a SQL TINYINT value when it sends it to the database. - * - * @param parameterIndex the first parameter is 1... - * @param x the parameter value - * @exception SQLException if a database access error occurs - */ - public void setByte(int parameterIndex, byte x) throws SQLException - { - bind(parameterIndex, Integer.toString(x), PG_INT2); - } - - /* - * Set a parameter to a Java short value. The driver converts this - * to a SQL SMALLINT value when it sends it to the database. - * - * @param parameterIndex the first parameter is 1... - * @param x the parameter value - * @exception SQLException if a database access error occurs - */ - public void setShort(int parameterIndex, short x) throws SQLException - { - bind(parameterIndex, Integer.toString(x), PG_INT2); - } - - /* - * Set a parameter to a Java int value. The driver converts this to - * a SQL INTEGER value when it sends it to the database. - * - * @param parameterIndex the first parameter is 1... - * @param x the parameter value - * @exception SQLException if a database access error occurs - */ - public void setInt(int parameterIndex, int x) throws SQLException - { - bind(parameterIndex, Integer.toString(x), PG_INTEGER); - } - - /* - * Set a parameter to a Java long value. The driver converts this to - * a SQL BIGINT value when it sends it to the database. - * - * @param parameterIndex the first parameter is 1... - * @param x the parameter value - * @exception SQLException if a database access error occurs - */ - public void setLong(int parameterIndex, long x) throws SQLException - { - bind(parameterIndex, Long.toString(x), PG_INT8); - } - - /* - * Set a parameter to a Java float value. The driver converts this - * to a SQL FLOAT value when it sends it to the database. - * - * @param parameterIndex the first parameter is 1... - * @param x the parameter value - * @exception SQLException if a database access error occurs - */ - public void setFloat(int parameterIndex, float x) throws SQLException - { - bind(parameterIndex, Float.toString(x), PG_FLOAT); - } - - /* - * Set a parameter to a Java double value. The driver converts this - * to a SQL DOUBLE value when it sends it to the database - * - * @param parameterIndex the first parameter is 1... - * @param x the parameter value - * @exception SQLException if a database access error occurs - */ - public void setDouble(int parameterIndex, double x) throws SQLException - { - bind(parameterIndex, Double.toString(x), PG_DOUBLE); - } - - /* - * Set a parameter to a java.lang.BigDecimal value. The driver - * converts this to a SQL NUMERIC value when it sends it to the - * database. - * - * @param parameterIndex the first parameter is 1... - * @param x the parameter value - * @exception SQLException if a database access error occurs - */ - public void setBigDecimal(int parameterIndex, BigDecimal x) throws SQLException - { - if (x == null) - setNull(parameterIndex, Types.DECIMAL); - else - { - bind(parameterIndex, x.toString(), PG_NUMERIC); - } - } - - /* - * Set a parameter to a Java String value. The driver converts this - * to a SQL VARCHAR or LONGVARCHAR value (depending on the arguments - * size relative to the driver's limits on VARCHARs) when it sends it - * to the database. - * - * @param parameterIndex the first parameter is 1... - * @param x the parameter value - * @exception SQLException if a database access error occurs - */ - public void setString(int parameterIndex, String x) throws SQLException - { - setString(parameterIndex, x, PG_TEXT); - } - - public void setString(int parameterIndex, String x, String type) throws SQLException - { - // if the passed string is null, then set this column to null - if (x == null) - setNull(parameterIndex, Types.VARCHAR); - else - { - // use the shared buffer object. Should never clash but this makes - // us thread safe! - synchronized (sbuf) - { - sbuf.setLength(0); - sbuf.ensureCapacity(2 + x.length() + (int)(x.length() / 10)); - sbuf.append('\''); - escapeString(x, sbuf); - sbuf.append('\''); - bind(parameterIndex, sbuf.toString(), type); - } - } - } - - private void escapeString(String p_input, StringBuffer p_output) { - for (int i = 0 ; i < p_input.length() ; ++i) - { - char c = p_input.charAt(i); - switch (c) - { - case '\\': - case '\'': - p_output.append('\\'); - p_output.append(c); - break; - case '\0': - throw new IllegalArgumentException("\\0 not allowed"); - default: - p_output.append(c); - } - } - } - - - /* - * Set a parameter to a Java array of bytes. The driver converts this - * to a SQL VARBINARY or LONGVARBINARY (depending on the argument's - * size relative to the driver's limits on VARBINARYs) when it sends - * it to the database. - * - * <p>Implementation note: - * <br>With org.postgresql, this creates a large object, and stores the - * objects oid in this column. - * - * @param parameterIndex the first parameter is 1... - * @param x the parameter value - * @exception SQLException if a database access error occurs - */ - public void setBytes(int parameterIndex, byte x[]) throws SQLException - { - if (connection.haveMinimumCompatibleVersion("7.2")) - { - //Version 7.2 supports the bytea datatype for byte arrays - if (null == x) - { - setNull(parameterIndex, Types.VARBINARY); - } - else - { - setString(parameterIndex, PGbytea.toPGString(x), PG_BYTEA); - } - } - else - { - //Version 7.1 and earlier support done as LargeObjects - LargeObjectManager lom = connection.getLargeObjectAPI(); - int oid = lom.create(); - LargeObject lob = lom.open(oid); - lob.write(x); - lob.close(); - setInt(parameterIndex, oid); - } - } - - /* - * Set a parameter to a java.sql.Date value. The driver converts this - * to a SQL DATE value when it sends it to the database. - * - * @param parameterIndex the first parameter is 1... - * @param x the parameter value - * @exception SQLException if a database access error occurs - */ - public void setDate(int parameterIndex, java.sql.Date x) throws SQLException - { - if (null == x) - { - setNull(parameterIndex, Types.DATE); - } - else - { - bind(parameterIndex, "'" + x.toString() + "'", PG_DATE); - } - } - - /* - * Set a parameter to a java.sql.Time value. The driver converts - * this to a SQL TIME value when it sends it to the database. - * - * @param parameterIndex the first parameter is 1...)); - * @param x the parameter value - * @exception SQLException if a database access error occurs - */ - public void setTime(int parameterIndex, Time x) throws SQLException - { - if (null == x) - { - setNull(parameterIndex, Types.TIME); - } - else - { - bind(parameterIndex, "'" + x.toString() + "'", PG_TIME); - } - } - - /* - * Set a parameter to a java.sql.Timestamp value. The driver converts - * this to a SQL TIMESTAMP value when it sends it to the database. - * - * @param parameterIndex the first parameter is 1... - * @param x the parameter value - * @exception SQLException if a database access error occurs - */ - public void setTimestamp(int parameterIndex, Timestamp x) throws SQLException - { - if (null == x) - { - setNull(parameterIndex, Types.TIMESTAMP); - } - else - { - // Use the shared StringBuffer - synchronized (sbuf) - { - sbuf.setLength(0); - sbuf.ensureCapacity(32); - sbuf.append("'"); - //format the timestamp - //we do our own formating so that we can get a format - //that works with both timestamp with time zone and - //timestamp without time zone datatypes. - //The format is '2002-01-01 23:59:59.123456-0130' - //we need to include the local time and timezone offset - //so that timestamp without time zone works correctly - int l_year = x.getYear() + 1900; - sbuf.append(l_year); - sbuf.append('-'); - int l_month = x.getMonth() + 1; - if (l_month < 10) - sbuf.append('0'); - sbuf.append(l_month); - sbuf.append('-'); - int l_day = x.getDate(); - if (l_day < 10) - sbuf.append('0'); - sbuf.append(l_day); - sbuf.append(' '); - int l_hours = x.getHours(); - if (l_hours < 10) - sbuf.append('0'); - sbuf.append(l_hours); - sbuf.append(':'); - int l_minutes = x.getMinutes(); - if (l_minutes < 10) - sbuf.append('0'); - sbuf.append(l_minutes); - sbuf.append(':'); - int l_seconds = x.getSeconds(); - if (l_seconds < 10) - sbuf.append('0'); - sbuf.append(l_seconds); - // Make decimal from nanos. - char[] l_decimal = {'0', '0', '0', '0', '0', '0', '0', '0', '0'}; - char[] l_nanos = Integer.toString(x.getNanos()).toCharArray(); - System.arraycopy(l_nanos, 0, l_decimal, l_decimal.length - l_nanos.length, l_nanos.length); - sbuf.append('.'); - if (connection.haveMinimumServerVersion("7.2")) - { - sbuf.append(l_decimal, 0, 6); - } - else - { - // Because 7.1 include bug that "hh:mm:59.999" becomes "hh:mm:60.00". - sbuf.append(l_decimal, 0, 2); - } - //add timezone offset - int l_offset = -(x.getTimezoneOffset()); - int l_houros = l_offset / 60; - if (l_houros >= 0) - { - sbuf.append('+'); - } - else - { - sbuf.append('-'); - } - if (l_houros > -10 && l_houros < 10) - sbuf.append('0'); - if (l_houros >= 0) - { - sbuf.append(l_houros); - } - else - { - sbuf.append(-l_houros); - } - int l_minos = l_offset - (l_houros * 60); - if (l_minos != 0) - { - if (l_minos > -10 && l_minos < 10) - sbuf.append('0'); - if (l_minos >= 0) - { - sbuf.append(l_minos); - } - else - { - sbuf.append(-l_minos); - } - } - sbuf.append("'"); - bind(parameterIndex, sbuf.toString(), PG_TIMESTAMPTZ); - } - - } - } - - /* - * When a very large ASCII value is input to a LONGVARCHAR parameter, - * it may be more practical to send it via a java.io.InputStream. - * JDBC will read the data from the stream as needed, until it reaches - * end-of-file. The JDBC driver will do any necessary conversion from - * ASCII to the database char format. - * - * <P><B>Note:</B> This stream object can either be a standard Java - * stream object or your own subclass that implements the standard - * interface. - * - * @param parameterIndex the first parameter is 1... - * @param x the parameter value - * @param length the number of bytes in the stream - * @exception SQLException if a database access error occurs - */ - public void setAsciiStream(int parameterIndex, InputStream x, int length) throws SQLException - { - if (connection.haveMinimumCompatibleVersion("7.2")) - { - //Version 7.2 supports AsciiStream for all PG text types (char, varchar, text) - //As the spec/javadoc for this method indicate this is to be used for - //large String values (i.e. LONGVARCHAR) PG doesn't have a separate - //long varchar datatype, but with toast all text datatypes are capable of - //handling very large values. Thus the implementation ends up calling - //setString() since there is no current way to stream the value to the server - try - { - InputStreamReader l_inStream = new InputStreamReader(x, "ASCII"); - char[] l_chars = new char[length]; - int l_charsRead = l_inStream.read(l_chars, 0, length); - setString(parameterIndex, new String(l_chars, 0, l_charsRead), PG_TEXT); - } - catch (UnsupportedEncodingException l_uee) - { - throw new PSQLException("postgresql.unusual", PSQLState.UNEXPECTED_ERROR, l_uee); - } - catch (IOException l_ioe) - { - throw new PSQLException("postgresql.unusual", PSQLState.UNEXPECTED_ERROR, l_ioe); - } - } - else - { - //Version 7.1 supported only LargeObjects by treating everything - //as binary data - setBinaryStream(parameterIndex, x, length); - } - } - - /* - * When a very large Unicode value is input to a LONGVARCHAR parameter, - * it may be more practical to send it via a java.io.InputStream. - * JDBC will read the data from the stream as needed, until it reaches - * end-of-file. The JDBC driver will do any necessary conversion from - * UNICODE to the database char format. - * - * <P><B>Note:</B> This stream object can either be a standard Java - * stream object or your own subclass that implements the standard - * interface. - * - * @param parameterIndex the first parameter is 1... - * @param x the parameter value - * @exception SQLException if a database access error occurs - */ - public void setUnicodeStream(int parameterIndex, InputStream x, int length) throws SQLException - { - if (connection.haveMinimumCompatibleVersion("7.2")) - { - //Version 7.2 supports AsciiStream for all PG text types (char, varchar, text) - //As the spec/javadoc for this method indicate this is to be used for - //large String values (i.e. LONGVARCHAR) PG doesn't have a separate - //long varchar datatype, but with toast all text datatypes are capable of - //handling very large values. Thus the implementation ends up calling - //setString() since there is no current way to stream the value to the server - try - { - InputStreamReader l_inStream = new InputStreamReader(x, "UTF-8"); - char[] l_chars = new char[length]; - int l_charsRead = l_inStream.read(l_chars, 0, length); - setString(parameterIndex, new String(l_chars, 0, l_charsRead), PG_TEXT); - } - catch (UnsupportedEncodingException l_uee) - { - throw new PSQLException("postgresql.unusual", PSQLState.UNEXPECTED_ERROR, l_uee); - } - catch (IOException l_ioe) - { - throw new PSQLException("postgresql.unusual", PSQLState.UNEXPECTED_ERROR, l_ioe); - } - } - else - { - //Version 7.1 supported only LargeObjects by treating everything - //as binary data - setBinaryStream(parameterIndex, x, length); - } - } - - /* - * When a very large binary value is input to a LONGVARBINARY parameter, - * it may be more practical to send it via a java.io.InputStream. - * JDBC will read the data from the stream as needed, until it reaches - * end-of-file. - * - * <P><B>Note:</B> This stream object can either be a standard Java - * stream object or your own subclass that implements the standard - * interface. - * - * @param parameterIndex the first parameter is 1... - * @param x the parameter value - * @exception SQLException if a database access error occurs - */ - public void setBinaryStream(int parameterIndex, InputStream x, int length) throws SQLException - { - if (connection.haveMinimumCompatibleVersion("7.2")) - { - //Version 7.2 supports BinaryStream for for the PG bytea type - //As the spec/javadoc for this method indicate this is to be used for - //large binary values (i.e. LONGVARBINARY) PG doesn't have a separate - //long binary datatype, but with toast the bytea datatype is capable of - //handling very large values. Thus the implementation ends up calling - //setBytes() since there is no current way to stream the value to the server - byte[] l_bytes = new byte[length]; - int l_bytesRead; - try - { - l_bytesRead = x.read(l_bytes, 0, length); - } - catch (IOException l_ioe) - { - throw new PSQLException("postgresql.unusual", PSQLState.UNEXPECTED_ERROR, l_ioe); - } - if (l_bytesRead == length) - { - setBytes(parameterIndex, l_bytes); - } - // x.read will return -1 not 0 on an empty InputStream - else if (l_bytesRead == -1) - { - setBytes(parameterIndex, new byte[0]); - } - else - { - //the stream contained less data than they said - byte[] l_bytes2 = new byte[l_bytesRead]; - System.arraycopy(l_bytes, 0, l_bytes2, 0, l_bytesRead); - setBytes(parameterIndex, l_bytes2); - } - } - else - { - //Version 7.1 only supported streams for LargeObjects - //but the jdbc spec indicates that streams should be - //available for LONGVARBINARY instead - LargeObjectManager lom = connection.getLargeObjectAPI(); - int oid = lom.create(); - LargeObject lob = lom.open(oid); - OutputStream los = lob.getOutputStream(); - try - { - // could be buffered, but then the OutputStream returned by LargeObject - // is buffered internally anyhow, so there would be no performance - // boost gained, if anything it would be worse! - int c = x.read(); - int p = 0; - while (c > -1 && p < length) - { - los.write(c); - c = x.read(); - p++; - } - los.close(); - } - catch (IOException se) - { - throw new PSQLException("postgresql.unusual", PSQLState.UNEXPECTED_ERROR, se); - } - // lob is closed by the stream so don't call lob.close() - setInt(parameterIndex, oid); - } - } - - - /* - * In general, parameter values remain in force for repeated used of a - * Statement. Setting a parameter value automatically clears its - * previous value. However, in coms cases, it is useful to immediately - * release the resources used by the current parameter values; this - * can be done by calling clearParameters - * - * @exception SQLException if a database access error occurs - */ - public void clearParameters() throws SQLException - { - int i; - - for (i = 0 ; i < m_binds.length ; i++) - { - m_binds[i] = null; - m_bindTypes[i] = null; - } - } - - // Helper method that extracts numeric values from an arbitary Object. - private String numericValueOf(Object x) - { - if (x instanceof Boolean) - return ((Boolean)x).booleanValue() ? "1" :"0"; - else if (x instanceof Integer || x instanceof Long || - x instanceof Double || x instanceof Short || - x instanceof Number || x instanceof Float) - return x.toString(); - else - //ensure the value is a valid numeric value to avoid - //sql injection attacks - return new BigDecimal(x.toString()).toString(); - } - - /* - * Set the value of a parameter using an object; use the java.lang - * equivalent objects for integral values. - * - * <P>The given Java object will be converted to the targetSqlType before - * being sent to the database. - * - * <P>note that this method may be used to pass database-specific - * abstract data types. This is done by using a Driver-specific - * Java type and using a targetSqlType of java.sql.Types.OTHER - * - * @param parameterIndex the first parameter is 1... - * @param x the object containing the input parameter value - * @param targetSqlType The SQL type to be send to the database - * @param scale For java.sql.Types.DECIMAL or java.sql.Types.NUMERIC - * * types this is the number of digits after the decimal. For - * * all other types this value will be ignored. - * @exception SQLException if a database access error occurs - */ - public void setObject(int parameterIndex, Object x, int targetSqlType, int scale) throws SQLException - { - if (x == null) - { - setNull(parameterIndex, targetSqlType); - return ; - } - switch (targetSqlType) - { - case Types.INTEGER: - bind(parameterIndex, numericValueOf(x), PG_INTEGER); - break; - case Types.TINYINT: - case Types.SMALLINT: - bind(parameterIndex, numericValueOf(x), PG_INT2); - break; - case Types.BIGINT: - bind(parameterIndex, numericValueOf(x), PG_INT8); - break; - case Types.REAL: - case Types.FLOAT: - bind(parameterIndex, numericValueOf(x), PG_FLOAT); - break; - case Types.DOUBLE: - bind(parameterIndex, numericValueOf(x), PG_DOUBLE); - break; - case Types.DECIMAL: - case Types.NUMERIC: - bind(parameterIndex, numericValueOf(x), PG_NUMERIC); - break; - case Types.CHAR: - case Types.VARCHAR: - case Types.LONGVARCHAR: - setString(parameterIndex, x.toString()); - break; - case Types.DATE: - if (x instanceof java.sql.Date) - setDate(parameterIndex, (java.sql.Date)x); - else - { - java.sql.Date tmpd = (x instanceof java.util.Date) ? new java.sql.Date(((java.util.Date)x).getTime()) : dateFromString(x.toString()); - setDate(parameterIndex, tmpd); - } - break; - case Types.TIME: - if (x instanceof java.sql.Time) - setTime(parameterIndex, (java.sql.Time)x); - else - { - java.sql.Time tmpt = (x instanceof java.util.Date) ? new java.sql.Time(((java.util.Date)x).getTime()) : timeFromString(x.toString()); - setTime(parameterIndex, tmpt); - } - break; - case Types.TIMESTAMP: - if (x instanceof java.sql.Timestamp) - setTimestamp(parameterIndex ,(java.sql.Timestamp)x); - else - { - java.sql.Timestamp tmpts = (x instanceof java.util.Date) ? new java.sql.Timestamp(((java.util.Date)x).getTime()) : timestampFromString(x.toString()); - setTimestamp(parameterIndex, tmpts); - } - break; - case Types.BIT: - if (x instanceof Boolean) - { - bind(parameterIndex, ((Boolean)x).booleanValue() ? "'1'" : "'0'", PG_BOOLEAN); - } - else if (x instanceof String) - { - bind(parameterIndex, Boolean.valueOf(x.toString()).booleanValue() ? "'1'" : "'0'", PG_BOOLEAN); - } - else if (x instanceof Number) - { - bind(parameterIndex, ((Number)x).intValue()!=0 ? "'1'" : "'0'", PG_BOOLEAN); - } - else - { - throw new PSQLException("postgresql.prep.type", PSQLState.INVALID_PARAMETER_TYPE); - } - break; - case Types.BINARY: - case Types.VARBINARY: - case Types.LONGVARBINARY: - setObject(parameterIndex, x); - break; - case Types.OTHER: - if (x instanceof PGobject) - setString(parameterIndex, ((PGobject)x).getValue(), ((PGobject)x).getType()); - else - throw new PSQLException("postgresql.prep.type", PSQLState.INVALID_PARAMETER_TYPE); - break; - default: - throw new PSQLException("postgresql.prep.type", PSQLState.INVALID_PARAMETER_TYPE); - } - } - - public void setObject(int parameterIndex, Object x, int targetSqlType) throws SQLException - { - setObject(parameterIndex, x, targetSqlType, 0); - } - - /* - * This stores an Object into a parameter. - */ - public void setObject(int parameterIndex, Object x) throws SQLException - { - if (x == null) - { - setNull(parameterIndex, Types.OTHER); - return ; - } - if (x instanceof String) - setString(parameterIndex, (String)x); - else if (x instanceof BigDecimal) - setBigDecimal(parameterIndex, (BigDecimal)x); - else if (x instanceof Short) - setShort(parameterIndex, ((Short)x).shortValue()); - else if (x instanceof Integer) - setInt(parameterIndex, ((Integer)x).intValue()); - else if (x instanceof Long) - setLong(parameterIndex, ((Long)x).longValue()); - else if (x instanceof Float) - setFloat(parameterIndex, ((Float)x).floatValue()); - else if (x instanceof Double) - setDouble(parameterIndex, ((Double)x).doubleValue()); - else if (x instanceof byte[]) - setBytes(parameterIndex, (byte[])x); - else if (x instanceof java.sql.Date) - setDate(parameterIndex, (java.sql.Date)x); - else if (x instanceof Time) - setTime(parameterIndex, (Time)x); - else if (x instanceof Timestamp) - setTimestamp(parameterIndex, (Timestamp)x); - else if (x instanceof Boolean) - setBoolean(parameterIndex, ((Boolean)x).booleanValue()); - else if (x instanceof PGobject) - setString(parameterIndex, ((PGobject)x).getValue(), PG_TEXT); - else - // Try to store as a string in database - setString(parameterIndex, x.toString(), PG_TEXT); - } - - /* - * Before executing a stored procedure call you must explicitly - * call registerOutParameter to register the java.sql.Type of each - * out parameter. - * - * <p>Note: When reading the value of an out parameter, you must use - * the getXXX method whose Java type XXX corresponds to the - * parameter's registered SQL type. - * - * ONLY 1 RETURN PARAMETER if {?= call ..} syntax is used - * - * @param parameterIndex the first parameter is 1, the second is 2,... - * @param sqlType SQL type code defined by java.sql.Types; for - * parameters of type Numeric or Decimal use the version of - * registerOutParameter that accepts a scale value - * @exception SQLException if a database-access error occurs. - */ - public void registerOutParameter(int parameterIndex, int sqlType) throws SQLException - { - if (parameterIndex != 1) - throw new PSQLException ("postgresql.call.noinout", PSQLState.STATEMENT_NOT_ALLOWED_IN_FUNCTION_CALL); - if (!isFunction) - throw new PSQLException ("postgresql.call.procasfunc", PSQLState.STATEMENT_NOT_ALLOWED_IN_FUNCTION_CALL,originalSql); - - // functionReturnType contains the user supplied value to check - // testReturn contains a modified version to make it easier to - // check the getXXX methods.. - functionReturnType = sqlType; - testReturn = sqlType; - if (functionReturnType == Types.CHAR || - functionReturnType == Types.LONGVARCHAR) - testReturn = Types.VARCHAR; - else if (functionReturnType == Types.FLOAT) - testReturn = Types.REAL; // changes to streamline later error checking - returnTypeSet = true; - } - - /* - * You must also specify the scale for numeric/decimal types: - * - * <p>Note: When reading the value of an out parameter, you must use - * the getXXX method whose Java type XXX corresponds to the - * parameter's registered SQL type. - * - * @param parameterIndex the first parameter is 1, the second is 2,... - * @param sqlType use either java.sql.Type.NUMERIC or java.sql.Type.DECIMAL - * @param scale a value greater than or equal to zero representing the - * desired number of digits to the right of the decimal point - * @exception SQLException if a database-access error occurs. - */ - public void registerOutParameter(int parameterIndex, int sqlType, - int scale) throws SQLException - { - registerOutParameter (parameterIndex, sqlType); // ignore for now.. - } - - /* - * An OUT parameter may have the value of SQL NULL; wasNull - * reports whether the last value read has this special value. - * - * <p>Note: You must first call getXXX on a parameter to read its - * value and then call wasNull() to see if the value was SQL NULL. - * @return true if the last parameter read was SQL NULL - * @exception SQLException if a database-access error occurs. - */ - public boolean wasNull() throws SQLException - { - // check to see if the last access threw an exception - return (callResult == null); - } - - /* - * Get the value of a CHAR, VARCHAR, or LONGVARCHAR parameter as a - * Java String. - * - * @param parameterIndex the first parameter is 1, the second is 2,... - * @return the parameter value; if the value is SQL NULL, the result is null - * @exception SQLException if a database-access error occurs. - */ - public String getString(int parameterIndex) throws SQLException - { - checkIndex (parameterIndex, Types.VARCHAR, "String"); - return (String)callResult; - } - - - /* - * Get the value of a BIT parameter as a Java boolean. - * - * @param parameterIndex the first parameter is 1, the second is 2,... - * @return the parameter value; if the value is SQL NULL, the result is false - * @exception SQLException if a database-access error occurs. - */ - public boolean getBoolean(int parameterIndex) throws SQLException - { - checkIndex (parameterIndex, Types.BIT, "Boolean"); - if (callResult == null) - return false; - return ((Boolean)callResult).booleanValue (); - } - - /* - * Get the value of a TINYINT parameter as a Java byte. - * - * @param parameterIndex the first parameter is 1, the second is 2,... - * @return the parameter value; if the value is SQL NULL, the result is 0 - * @exception SQLException if a database-access error occurs. - */ - public byte getByte(int parameterIndex) throws SQLException - { - checkIndex (parameterIndex, Types.TINYINT, "Byte"); - if (callResult == null) - return 0; - return (byte)((Integer)callResult).intValue (); - } - - /* - * Get the value of a SMALLINT parameter as a Java short. - * - * @param parameterIndex the first parameter is 1, the second is 2,... - * @return the parameter value; if the value is SQL NULL, the result is 0 - * @exception SQLException if a database-access error occurs. - */ - public short getShort(int parameterIndex) throws SQLException - { - checkIndex (parameterIndex, Types.SMALLINT, "Short"); - if (callResult == null) - return 0; - return (short)((Integer)callResult).intValue (); - } - - - /* - * Get the value of an INTEGER parameter as a Java int. - * - * @param parameterIndex the first parameter is 1, the second is 2,... - * @return the parameter value; if the value is SQL NULL, the result is 0 - * @exception SQLException if a database-access error occurs. - */ - public int getInt(int parameterIndex) throws SQLException - { - checkIndex (parameterIndex, Types.INTEGER, "Int"); - if (callResult == null) - return 0; - return ((Integer)callResult).intValue (); - } - - /* - * Get the value of a BIGINT parameter as a Java long. - * - * @param parameterIndex the first parameter is 1, the second is 2,... - * @return the parameter value; if the value is SQL NULL, the result is 0 - * @exception SQLException if a database-access error occurs. - */ - public long getLong(int parameterIndex) throws SQLException - { - checkIndex (parameterIndex, Types.BIGINT, "Long"); - if (callResult == null) - return 0; - return ((Long)callResult).longValue (); - } - - /* - * Get the value of a FLOAT parameter as a Java float. - * - * @param parameterIndex the first parameter is 1, the second is 2,... - * @return the parameter value; if the value is SQL NULL, the result is 0 - * @exception SQLException if a database-access error occurs. - */ - public float getFloat(int parameterIndex) throws SQLException - { - checkIndex (parameterIndex, Types.REAL, "Float"); - if (callResult == null) - return 0; - return ((Float)callResult).floatValue (); - } - - /* - * Get the value of a DOUBLE parameter as a Java double. - * - * @param parameterIndex the first parameter is 1, the second is 2,... - * @return the parameter value; if the value is SQL NULL, the result is 0 - * @exception SQLException if a database-access error occurs. - */ - public double getDouble(int parameterIndex) throws SQLException - { - checkIndex (parameterIndex, Types.DOUBLE, "Double"); - if (callResult == null) - return 0; - return ((Double)callResult).doubleValue (); - } - - /* - * Get the value of a NUMERIC parameter as a java.math.BigDecimal - * object. - * - * @param parameterIndex the first parameter is 1, the second is 2,... - * @param scale a value greater than or equal to zero representing the - * desired number of digits to the right of the decimal point - * @return the parameter value; if the value is SQL NULL, the result is null - * @exception SQLException if a database-access error occurs. - * @deprecated in Java2.0 - */ - public BigDecimal getBigDecimal(int parameterIndex, int scale) - throws SQLException - { - checkIndex (parameterIndex, Types.NUMERIC, "BigDecimal"); - return ((BigDecimal)callResult); - } - - /* - * Get the value of a SQL BINARY or VARBINARY parameter as a Java - * byte[] - * - * @param parameterIndex the first parameter is 1, the second is 2,... - * @return the parameter value; if the value is SQL NULL, the result is null - * @exception SQLException if a database-access error occurs. - */ - public byte[] getBytes(int parameterIndex) throws SQLException - { - checkIndex (parameterIndex, Types.VARBINARY, Types.BINARY, "Bytes"); - return ((byte [])callResult); - } - - - /* - * Get the value of a SQL DATE parameter as a java.sql.Date object - * - * @param parameterIndex the first parameter is 1, the second is 2,... - * @return the parameter value; if the value is SQL NULL, the result is null - * @exception SQLException if a database-access error occurs. - */ - public java.sql.Date getDate(int parameterIndex) throws SQLException - { - checkIndex (parameterIndex, Types.DATE, "Date"); - return (java.sql.Date)callResult; - } - - /* - * Get the value of a SQL TIME parameter as a java.sql.Time object. - * - * @param parameterIndex the first parameter is 1, the second is 2,... - * @return the parameter value; if the value is SQL NULL, the result is null - * @exception SQLException if a database-access error occurs. - */ - public java.sql.Time getTime(int parameterIndex) throws SQLException - { - checkIndex (parameterIndex, Types.TIME, "Time"); - return (java.sql.Time)callResult; - } - - /* - * Get the value of a SQL TIMESTAMP parameter as a java.sql.Timestamp object. - * - * @param parameterIndex the first parameter is 1, the second is 2,... - * @return the parameter value; if the value is SQL NULL, the result is null - * @exception SQLException if a database-access error occurs. - */ - public java.sql.Timestamp getTimestamp(int parameterIndex) - throws SQLException - { - checkIndex (parameterIndex, Types.TIMESTAMP, "Timestamp"); - return (java.sql.Timestamp)callResult; - } - - // getObject returns a Java object for the parameter. - // See the JDBC spec's "Dynamic Programming" chapter for details. - /* - * Get the value of a parameter as a Java object. - * - * <p>This method returns a Java object whose type coresponds to the - * SQL type that was registered for this parameter using - * registerOutParameter. - * - * <P>Note that this method may be used to read datatabase-specific, - * abstract data types. This is done by specifying a targetSqlType - * of java.sql.types.OTHER, which allows the driver to return a - * database-specific Java type. - * - * <p>See the JDBC spec's "Dynamic Programming" chapter for details. - * - * @param parameterIndex the first parameter is 1, the second is 2,... - * @return A java.lang.Object holding the OUT parameter value. - * @exception SQLException if a database-access error occurs. - */ - public Object getObject(int parameterIndex) - throws SQLException - { - checkIndex (parameterIndex); - return callResult; - } - - //This method is implemeted in jdbc2 - public int getResultSetConcurrency() throws SQLException - { - return 0; - } - - /* - * Returns the SQL statement with the current template values - * substituted. - */ - public String toString() - { - if (m_sqlFragments == null) - return super.toString(); - - synchronized (sbuf) - { - sbuf.setLength(0); - int i; - - for (i = 0 ; i < m_binds.length ; ++i) - { - sbuf.append (m_sqlFragments[i]); - if (m_binds[i] == null) - sbuf.append( '?' ); - else - sbuf.append (m_binds[i]); - } - sbuf.append(m_sqlFragments[m_binds.length]); - return sbuf.toString(); - } - } - - /* - * Note if s is a String it should be escaped by the caller to avoid SQL - * injection attacks. It is not done here for efficency reasons as - * most calls to this method do not require escaping as the source - * of the string is known safe (i.e. Integer.toString()) - */ - private void bind(int paramIndex, Object s, String type) throws SQLException - { - if (paramIndex < 1 || paramIndex > m_binds.length) - throw new PSQLException("postgresql.prep.range", PSQLState.INVALID_PARAMETER_VALUE); - if (paramIndex == 1 && isFunction) // need to registerOut instead - throw new PSQLException ("postgresql.call.funcover"); - m_binds[paramIndex - 1] = s; - m_bindTypes[paramIndex - 1] = type; - } - - /** - * this method will turn a string of the form - * {? = call <some_function> (?, [?,..]) } - * into the PostgreSQL format which is - * select <some_function> (?, [?, ...]) as result - * or select * from <some_function> (?, [?, ...]) as result (7.3) - * - */ - private String modifyJdbcCall(String p_sql) throws SQLException - { - //Check that this is actually a call which should start with a { - //if not do nothing and treat this as a standard prepared sql - if (!p_sql.trim().startsWith("{")) { - return p_sql; - } - - // syntax checking is not complete only a few basics :( - originalSql = p_sql; // save for error msgs.. - String l_sql = p_sql; - int index = l_sql.indexOf ("="); // is implied func or proc? - boolean isValid = true; - if (index > -1) - { - isFunction = true; - isValid = l_sql.indexOf ("?") < index; // ? before = - } - l_sql = l_sql.trim (); - if (l_sql.startsWith ("{") && l_sql.endsWith ("}")) - { - l_sql = l_sql.substring (1, l_sql.length() - 1); - } - else - isValid = false; - index = l_sql.indexOf ("call"); - if (index == -1 || !isValid) - throw new PSQLException ("postgresql.call.malformed",PSQLState.STATEMENT_NOT_ALLOWED_IN_FUNCTION_CALL, - new Object[]{l_sql, JDBC_SYNTAX}); - l_sql = l_sql.replace ('{', ' '); // replace these characters - l_sql = l_sql.replace ('}', ' '); - l_sql = l_sql.replace (';', ' '); - - // this removes the 'call' string and also puts a hidden '?' - // at the front of the line for functions, this will - // allow the registerOutParameter to work correctly - // because in the source sql there was one more ? for the return - // value that is not needed by the postgres syntax. But to make - // sure that the parameter numbers are the same as in the original - // sql we add a dummy parameter in this case - l_sql = (isFunction ? "?" : "") + l_sql.substring (index + 4); - if (connection.haveMinimumServerVersion("7.3")) { - l_sql = "select * from " + l_sql + " as " + RESULT_ALIAS + ";"; - } else { - l_sql = "select " + l_sql + " as " + RESULT_ALIAS + ";"; - } - return l_sql; - } - - /** helperfunction for the getXXX calls to check isFunction and index == 1 - * Compare BOTH type fields against the return type. - */ - protected void checkIndex (int parameterIndex, int type1, int type2, String getName) - throws SQLException - { - checkIndex (parameterIndex); - if (type1 != this.testReturn && type2 != this.testReturn) - throw new PSQLException("postgresql.call.wrongget", PSQLState.MOST_SPECIFIC_TYPE_DOES_NOT_MATCH, - new Object[]{"java.sql.Types=" + testReturn, - getName, - "java.sql.Types=" + type1}); - } - - /** helperfunction for the getXXX calls to check isFunction and index == 1 - */ - protected void checkIndex (int parameterIndex, int type, String getName) - throws SQLException - { - checkIndex (parameterIndex); - if (type != this.testReturn) - throw new PSQLException("postgresql.call.wrongget", PSQLState.MOST_SPECIFIC_TYPE_DOES_NOT_MATCH, - new Object[]{"java.sql.Types=" + testReturn, - getName, - "java.sql.Types=" + type}); - } - - /** helperfunction for the getXXX calls to check isFunction and index == 1 - * @param parameterIndex index of getXXX (index) - * check to make sure is a function and index == 1 - */ - private void checkIndex (int parameterIndex) throws SQLException - { - if (!isFunction) - throw new PSQLException("postgresql.call.noreturntype", PSQLState.STATEMENT_NOT_ALLOWED_IN_FUNCTION_CALL); - if (parameterIndex != 1) - throw new PSQLException("postgresql.call.noinout", PSQLState.STATEMENT_NOT_ALLOWED_IN_FUNCTION_CALL); - } - - - - public void setUseServerPrepare(boolean flag) throws SQLException { - //Server side prepared statements were introduced in 7.3 - if (connection.haveMinimumServerVersion("7.3")) { - if (m_useServerPrepare != flag) - deallocateQuery(); - m_useServerPrepare = flag; - } else { - //This is a pre 7.3 server so no op this method - //which means we will never turn on the flag to use server - //prepared statements and thus regular processing will continue - } - } - - public boolean isUseServerPrepare() - { - return m_useServerPrepare; - } - - private java.sql.Date dateFromString (String s) throws SQLException - { - int timezone = 0; - long millis = 0; - long localoffset = 0; - int timezoneLocation = (s.indexOf('+') == -1) ? s.lastIndexOf("-") : s.indexOf('+'); - //if the last index of '-' or '+' is past 8. we are guaranteed that it is a timezone marker - //shortest = yyyy-m-d - //longest = yyyy-mm-dd - try - { - timezone = (timezoneLocation>7) ? timezoneLocation : s.length(); - millis = java.sql.Date.valueOf(s.substring(0,timezone)).getTime(); - } - catch (Exception e) - { - throw new PSQLException("postgresql.format.baddate", PSQLState.BAD_DATETIME_FORMAT, s , "yyyy-MM-dd[-tz]"); - } - timezone = 0; - if (timezoneLocation>7 && timezoneLocation+3 == s.length()) - { - timezone = Integer.parseInt(s.substring(timezoneLocation+1,s.length())); - localoffset = java.util.Calendar.getInstance().getTimeZone().getRawOffset(); - if (java.util.Calendar.getInstance().getTimeZone().inDaylightTime(new java.sql.Date(millis))) - localoffset += 60*60*1000; - if (s.charAt(timezoneLocation)=='+') - timezone*=-1; - } - millis = millis + timezone*60*60*1000 + localoffset; - return new java.sql.Date(millis); - } - - private java.sql.Time timeFromString (String s) throws SQLException - { - int timezone = 0; - long millis = 0; - long localoffset = 0; - int timezoneLocation = (s.indexOf('+') == -1) ? s.lastIndexOf("-") : s.indexOf('+'); - //if the index of the last '-' or '+' is greater than 0 that means this time has a timezone. - //everything earlier than that position, we treat as the time and parse it as such. - try - { - timezone = (timezoneLocation==-1) ? s.length() : timezoneLocation; - millis = java.sql.Time.valueOf(s.substring(0,timezone)).getTime(); - } - catch (Exception e) - { - throw new PSQLException("postgresql.format.badtime", PSQLState.BAD_DATETIME_FORMAT, s, "HH:mm:ss[-tz]"); - } - timezone = 0; - if (timezoneLocation != -1 && timezoneLocation+3 == s.length()) - { - timezone = Integer.parseInt(s.substring(timezoneLocation+1,s.length())); - localoffset = java.util.Calendar.getInstance().getTimeZone().getRawOffset(); - if (java.util.Calendar.getInstance().getTimeZone().inDaylightTime(new java.sql.Date(millis))) - localoffset += 60*60*1000; - if (s.charAt(timezoneLocation)=='+') - timezone*=-1; - } - millis = millis + timezone*60*60*1000 + localoffset; - return new java.sql.Time(millis); - } - - private java.sql.Timestamp timestampFromString (String s) throws SQLException - { - int timezone = 0; - long millis = 0; - long localoffset = 0; - int nanosVal = 0; - int timezoneLocation = (s.indexOf('+') == -1) ? s.lastIndexOf("-") : s.indexOf('+'); - int nanospos = s.indexOf("."); - //if there is a '.', that means there are nanos info, and we take the timestamp up to that point - //if not, then we check to see if the last +/- (to indicate a timezone) is greater than 8 - //8 is because the shortest date, will have last '-' at position 7. e.g yyyy-x-x - try - { - if (nanospos != -1) - timezone = nanospos; - else if (timezoneLocation > 8) - timezone = timezoneLocation; - else - timezone = s.length(); - millis = java.sql.Timestamp.valueOf(s.substring(0,timezone)).getTime(); - } - catch (Exception e) - { - throw new PSQLException("postgresql.format.badtimestamp", PSQLState.BAD_DATETIME_FORMAT, s, "yyyy-MM-dd HH:mm:ss[.xxxxxx][-tz]"); - } - timezone = 0; - if (nanospos != -1) - { - int tmploc = (timezoneLocation > 8) ? timezoneLocation : s.length(); - nanosVal = Integer.parseInt(s.substring(nanospos+1,tmploc)); - int diff = 8-((tmploc-1)-(nanospos+1)); - for (int i=0;i<diff;i++) - nanosVal*=10; - } - if (timezoneLocation>8 && timezoneLocation+3 == s.length()) - { - timezone = Integer.parseInt(s.substring(timezoneLocation+1,s.length())); - localoffset = java.util.Calendar.getInstance().getTimeZone().getRawOffset(); - if (java.util.Calendar.getInstance().getTimeZone().inDaylightTime(new java.sql.Date(millis))) - localoffset += 60*60*1000; - if (s.charAt(timezoneLocation)=='+') - timezone*=-1; - } - millis = millis + timezone*60*60*1000 + localoffset; - java.sql.Timestamp tmpts = new java.sql.Timestamp(millis); - tmpts.setNanos(nanosVal); - return tmpts; - } - - - private static final String PG_TEXT = "text"; - private static final String PG_INTEGER = "integer"; - private static final String PG_INT2 = "int2"; - private static final String PG_INT8 = "int8"; - private static final String PG_NUMERIC = "numeric"; - private static final String PG_FLOAT = "float"; - private static final String PG_DOUBLE = "double precision"; - private static final String PG_BOOLEAN = "boolean"; - private static final String PG_DATE = "date"; - private static final String PG_TIME = "time"; - private static final String PG_TIMESTAMPTZ = "timestamptz"; - private static final String PG_BYTEA = "bytea"; - - -} diff --git a/src/interfaces/jdbc/org/postgresql/jdbc1/Jdbc1CallableStatement.java b/src/interfaces/jdbc/org/postgresql/jdbc1/Jdbc1CallableStatement.java deleted file mode 100644 index 697a1869ab7..00000000000 --- a/src/interfaces/jdbc/org/postgresql/jdbc1/Jdbc1CallableStatement.java +++ /dev/null @@ -1,28 +0,0 @@ -package org.postgresql.jdbc1; - - -import java.sql.*; -import java.util.Vector; -import org.postgresql.PGRefCursorResultSet; -import org.postgresql.core.BaseResultSet; -import org.postgresql.core.Field; - -public class Jdbc1CallableStatement extends AbstractJdbc1Statement implements java.sql.CallableStatement -{ - - public Jdbc1CallableStatement(Jdbc1Connection connection, String sql) throws SQLException - { - super(connection, sql); - } - - public BaseResultSet createResultSet (Field[] fields, java.util.Vector tuples, String status, int updateCount, long insertOID, boolean binaryCursor) throws SQLException - { - return new Jdbc1ResultSet(this, fields, tuples, status, updateCount, insertOID, binaryCursor); - } - - public PGRefCursorResultSet createRefCursorResultSet (String cursorName) throws SQLException - { - return new Jdbc1RefCursorResultSet(this, cursorName); - } -} - diff --git a/src/interfaces/jdbc/org/postgresql/jdbc1/Jdbc1Connection.java b/src/interfaces/jdbc/org/postgresql/jdbc1/Jdbc1Connection.java deleted file mode 100644 index 15d11f5a286..00000000000 --- a/src/interfaces/jdbc/org/postgresql/jdbc1/Jdbc1Connection.java +++ /dev/null @@ -1,41 +0,0 @@ -package org.postgresql.jdbc1; - - -import java.util.Vector; -import java.sql.*; -import org.postgresql.core.Field; -import org.postgresql.util.PSQLException; - -/* $PostgreSQL: pgsql/src/interfaces/jdbc/org/postgresql/jdbc1/Jdbc1Connection.java,v 1.8 2003/11/29 19:52:10 pgsql Exp $ - * This class implements the java.sql.Connection interface for JDBC1. - * However most of the implementation is really done in - * org.postgresql.jdbc1.AbstractJdbc1Connection - */ -public class Jdbc1Connection extends org.postgresql.jdbc1.AbstractJdbc1Connection implements java.sql.Connection -{ - - public java.sql.Statement createStatement() throws SQLException - { - return new org.postgresql.jdbc1.Jdbc1Statement(this); - } - - public java.sql.PreparedStatement prepareStatement(String sql) throws SQLException - { - return new org.postgresql.jdbc1.Jdbc1PreparedStatement(this, sql); - } - - public java.sql.CallableStatement prepareCall(String sql) throws SQLException - { - return new org.postgresql.jdbc1.Jdbc1CallableStatement(this, sql); - } - - public java.sql.DatabaseMetaData getMetaData() throws SQLException - { - if (metadata == null) - metadata = new org.postgresql.jdbc1.Jdbc1DatabaseMetaData(this); - return metadata; - } - -} - - diff --git a/src/interfaces/jdbc/org/postgresql/jdbc1/Jdbc1DatabaseMetaData.java b/src/interfaces/jdbc/org/postgresql/jdbc1/Jdbc1DatabaseMetaData.java deleted file mode 100644 index fde36f5511c..00000000000 --- a/src/interfaces/jdbc/org/postgresql/jdbc1/Jdbc1DatabaseMetaData.java +++ /dev/null @@ -1,16 +0,0 @@ -package org.postgresql.jdbc1; - - -import java.sql.*; -import java.util.*; -import org.postgresql.core.Field; -import org.postgresql.util.PSQLException; - -public class Jdbc1DatabaseMetaData extends AbstractJdbc1DatabaseMetaData implements java.sql.DatabaseMetaData -{ - public Jdbc1DatabaseMetaData(Jdbc1Connection conn) - { - super(conn); - } - -} diff --git a/src/interfaces/jdbc/org/postgresql/jdbc1/Jdbc1PreparedStatement.java b/src/interfaces/jdbc/org/postgresql/jdbc1/Jdbc1PreparedStatement.java deleted file mode 100644 index a80928ebddf..00000000000 --- a/src/interfaces/jdbc/org/postgresql/jdbc1/Jdbc1PreparedStatement.java +++ /dev/null @@ -1,26 +0,0 @@ -package org.postgresql.jdbc1; - - -import java.sql.*; -import org.postgresql.PGRefCursorResultSet; -import org.postgresql.core.BaseResultSet; -import org.postgresql.core.Field; - -public class Jdbc1PreparedStatement extends AbstractJdbc1Statement implements PreparedStatement -{ - - public Jdbc1PreparedStatement(Jdbc1Connection connection, String sql) throws SQLException - { - super(connection, sql); - } - - public BaseResultSet createResultSet (Field[] fields, java.util.Vector tuples, String status, int updateCount, long insertOID, boolean binaryCursor) throws SQLException - { - return new Jdbc1ResultSet(this, fields, tuples, status, updateCount, insertOID, binaryCursor); - } - - public PGRefCursorResultSet createRefCursorResultSet (String cursorName) throws SQLException - { - return new Jdbc1RefCursorResultSet(this, cursorName); - } -} diff --git a/src/interfaces/jdbc/org/postgresql/jdbc1/Jdbc1RefCursorResultSet.java b/src/interfaces/jdbc/org/postgresql/jdbc1/Jdbc1RefCursorResultSet.java deleted file mode 100644 index 7b83bf67427..00000000000 --- a/src/interfaces/jdbc/org/postgresql/jdbc1/Jdbc1RefCursorResultSet.java +++ /dev/null @@ -1,44 +0,0 @@ -package org.postgresql.jdbc1; - -import java.sql.SQLException; -import org.postgresql.core.QueryExecutor; -import org.postgresql.core.BaseStatement; -import org.postgresql.PGRefCursorResultSet; - -/** A real result set based on a ref cursor. - * - * @author Nic Ferrier <[email protected]> - */ -public class Jdbc1RefCursorResultSet extends Jdbc1ResultSet - implements PGRefCursorResultSet -{ - - // The name of the cursor being used. - String refCursorHandle; - - // Indicates when the result set has activaly bound to the cursor. - boolean isInitialized = false; - - - Jdbc1RefCursorResultSet(BaseStatement statement, String refCursorName) - { - super(statement, null, null, null, -1, 0L, false); - this.refCursorHandle = refCursorName; - } - - public String getRefCursor () - { - return refCursorHandle; - } - - public boolean next () throws SQLException - { - if (isInitialized) - return super.next(); - // Initialize this res set with the rows from the cursor. - String[] toExec = { "FETCH ALL IN \"" + refCursorHandle + "\";" }; - QueryExecutor.execute(toExec, new String[0], this); - isInitialized = true; - return super.next(); - } -} diff --git a/src/interfaces/jdbc/org/postgresql/jdbc1/Jdbc1ResultSet.java b/src/interfaces/jdbc/org/postgresql/jdbc1/Jdbc1ResultSet.java deleted file mode 100644 index 4e3dc05dadb..00000000000 --- a/src/interfaces/jdbc/org/postgresql/jdbc1/Jdbc1ResultSet.java +++ /dev/null @@ -1,28 +0,0 @@ -package org.postgresql.jdbc1; - - -import java.sql.*; -import java.util.Vector; -import org.postgresql.core.BaseStatement; -import org.postgresql.core.Field; - -/* $PostgreSQL: pgsql/src/interfaces/jdbc/org/postgresql/jdbc1/Jdbc1ResultSet.java,v 1.7 2003/11/29 19:52:10 pgsql Exp $ - * This class implements the java.sql.ResultSet interface for JDBC1. - * However most of the implementation is really done in - * org.postgresql.jdbc1.AbstractJdbc1ResultSet - */ -public class Jdbc1ResultSet extends org.postgresql.jdbc1.AbstractJdbc1ResultSet implements java.sql.ResultSet -{ - - public Jdbc1ResultSet(BaseStatement statement, Field[] fields, Vector tuples, String status, int updateCount, long insertOID, boolean binaryCursor) - { - super(statement, fields, tuples, status, updateCount, insertOID, binaryCursor); - } - - public java.sql.ResultSetMetaData getMetaData() throws SQLException - { - return new Jdbc1ResultSetMetaData(rows, fields); - } - -} - diff --git a/src/interfaces/jdbc/org/postgresql/jdbc1/Jdbc1ResultSetMetaData.java b/src/interfaces/jdbc/org/postgresql/jdbc1/Jdbc1ResultSetMetaData.java deleted file mode 100644 index 39748d67100..00000000000 --- a/src/interfaces/jdbc/org/postgresql/jdbc1/Jdbc1ResultSetMetaData.java +++ /dev/null @@ -1,14 +0,0 @@ -package org.postgresql.jdbc1; - -import java.util.Vector; -import org.postgresql.core.Field; - -public class Jdbc1ResultSetMetaData extends AbstractJdbc1ResultSetMetaData implements java.sql.ResultSetMetaData -{ - public Jdbc1ResultSetMetaData(Vector rows, Field[] fields) - { - super(rows, fields); - } - -} - diff --git a/src/interfaces/jdbc/org/postgresql/jdbc1/Jdbc1Statement.java b/src/interfaces/jdbc/org/postgresql/jdbc1/Jdbc1Statement.java deleted file mode 100644 index 0cfc4a61426..00000000000 --- a/src/interfaces/jdbc/org/postgresql/jdbc1/Jdbc1Statement.java +++ /dev/null @@ -1,32 +0,0 @@ -package org.postgresql.jdbc1; - - -import java.sql.*; -import java.util.Vector; -import org.postgresql.PGRefCursorResultSet; -import org.postgresql.core.BaseResultSet; -import org.postgresql.core.Field; - -/* $PostgreSQL: pgsql/src/interfaces/jdbc/org/postgresql/jdbc1/Jdbc1Statement.java,v 1.7 2003/11/29 19:52:10 pgsql Exp $ - * This class implements the java.sql.Statement interface for JDBC1. - * However most of the implementation is really done in - * org.postgresql.jdbc1.AbstractJdbc1Statement - */ -public class Jdbc1Statement extends org.postgresql.jdbc1.AbstractJdbc1Statement implements java.sql.Statement -{ - - public Jdbc1Statement (Jdbc1Connection c) - { - super(c); - } - - public BaseResultSet createResultSet (Field[] fields, Vector tuples, String status, int updateCount, long insertOID, boolean binaryCursor) throws SQLException - { - return new Jdbc1ResultSet(this, fields, tuples, status, updateCount, insertOID, binaryCursor); - } - - public PGRefCursorResultSet createRefCursorResultSet (String cursorName) throws SQLException - { - return new Jdbc1RefCursorResultSet(this, cursorName); - } -} diff --git a/src/interfaces/jdbc/org/postgresql/jdbc2/AbstractJdbc2Blob.java b/src/interfaces/jdbc/org/postgresql/jdbc2/AbstractJdbc2Blob.java deleted file mode 100644 index 27e10af2b95..00000000000 --- a/src/interfaces/jdbc/org/postgresql/jdbc2/AbstractJdbc2Blob.java +++ /dev/null @@ -1,54 +0,0 @@ -package org.postgresql.jdbc2; - -import org.postgresql.PGConnection; -import org.postgresql.largeobject.LargeObject; -import org.postgresql.largeobject.LargeObjectManager; -import java.io.InputStream; -import java.sql.Blob; -import java.sql.SQLException; - -public abstract class AbstractJdbc2Blob -{ - private int oid; - private LargeObject lo; - - public AbstractJdbc2Blob(PGConnection conn, int oid) throws SQLException - { - this.oid = oid; - LargeObjectManager lom = conn.getLargeObjectAPI(); - this.lo = lom.open(oid); - } - - public long length() throws SQLException - { - return lo.size(); - } - - public InputStream getBinaryStream() throws SQLException - { - return lo.getInputStream(); - } - - public byte[] getBytes(long pos, int length) throws SQLException - { - lo.seek((int)pos, LargeObject.SEEK_SET); - return lo.read(length); - } - - /* - * For now, this is not implemented. - */ - public long position(byte[] pattern, long start) throws SQLException - { - throw org.postgresql.Driver.notImplemented(); - } - - /* - * This should be simply passing the byte value of the pattern Blob - */ - public long position(Blob pattern, long start) throws SQLException - { - return position(pattern.getBytes(0, (int)pattern.length()), start); - } - -} diff --git a/src/interfaces/jdbc/org/postgresql/jdbc2/AbstractJdbc2Clob.java b/src/interfaces/jdbc/org/postgresql/jdbc2/AbstractJdbc2Clob.java deleted file mode 100644 index d1948f6331b..00000000000 --- a/src/interfaces/jdbc/org/postgresql/jdbc2/AbstractJdbc2Clob.java +++ /dev/null @@ -1,62 +0,0 @@ -package org.postgresql.jdbc2; - - -import org.postgresql.PGConnection; -import org.postgresql.largeobject.LargeObject; -import org.postgresql.largeobject.LargeObjectManager; -import java.io.InputStream; -import java.io.InputStreamReader; -import java.io.Reader; -import java.sql.Clob; -import java.sql.SQLException; - -public class AbstractJdbc2Clob -{ - private int oid; - private LargeObject lo; - - public AbstractJdbc2Clob(PGConnection conn, int oid) throws SQLException - { - this.oid = oid; - LargeObjectManager lom = conn.getLargeObjectAPI(); - this.lo = lom.open(oid); - } - - public long length() throws SQLException - { - return lo.size(); - } - - public InputStream getAsciiStream() throws SQLException - { - return lo.getInputStream(); - } - - public Reader getCharacterStream() throws SQLException - { - return new InputStreamReader(lo.getInputStream()); - } - - public String getSubString(long i, int j) throws SQLException - { - lo.seek((int)i - 1); - return new String(lo.read(j)); - } - - /* - * For now, this is not implemented. - */ - public long position(String pattern, long start) throws SQLException - { - throw org.postgresql.Driver.notImplemented(); - } - - /* - * This should be simply passing the byte value of the pattern Blob - */ - public long position(Clob pattern, long start) throws SQLException - { - throw org.postgresql.Driver.notImplemented(); - } - -} diff --git a/src/interfaces/jdbc/org/postgresql/jdbc2/AbstractJdbc2Connection.java b/src/interfaces/jdbc/org/postgresql/jdbc2/AbstractJdbc2Connection.java deleted file mode 100644 index feba229f7c5..00000000000 --- a/src/interfaces/jdbc/org/postgresql/jdbc2/AbstractJdbc2Connection.java +++ /dev/null @@ -1,173 +0,0 @@ -package org.postgresql.jdbc2; - - -import java.io.PrintWriter; -import java.sql.DriverManager; -import java.sql.SQLData; -import java.sql.SQLException; -import java.sql.Types; - -/* $PostgreSQL: pgsql/src/interfaces/jdbc/org/postgresql/jdbc2/AbstractJdbc2Connection.java,v 1.7 2003/11/29 19:52:10 pgsql Exp $ - * This class defines methods of the jdbc2 specification. This class extends - * org.postgresql.jdbc1.AbstractJdbc1Connection which provides the jdbc1 - * methods. The real Connection class (for jdbc2) is org.postgresql.jdbc2.Jdbc2Connection - */ -public abstract class AbstractJdbc2Connection extends org.postgresql.jdbc1.AbstractJdbc1Connection -{ - /* - * The current type mappings - */ - protected java.util.Map typemap; - - public java.sql.Statement createStatement() throws SQLException - { - // The spec says default of TYPE_FORWARD_ONLY but everyone is used to - // using TYPE_SCROLL_INSENSITIVE - return createStatement(java.sql.ResultSet.TYPE_SCROLL_INSENSITIVE, java.sql.ResultSet.CONCUR_READ_ONLY); - } - - public abstract java.sql.Statement createStatement(int resultSetType, int resultSetConcurrency) throws SQLException; - - public java.sql.PreparedStatement prepareStatement(String sql) throws SQLException - { - return prepareStatement(sql, java.sql.ResultSet.TYPE_SCROLL_INSENSITIVE, java.sql.ResultSet.CONCUR_READ_ONLY); - } - - public abstract java.sql.PreparedStatement prepareStatement(String sql, int resultSetType, int resultSetConcurrency) throws SQLException; - - public java.sql.CallableStatement prepareCall(String sql) throws SQLException - { - return prepareCall(sql, java.sql.ResultSet.TYPE_SCROLL_INSENSITIVE, java.sql.ResultSet.CONCUR_READ_ONLY); - } - - public abstract java.sql.CallableStatement prepareCall(String sql, int resultSetType, int resultSetConcurrency) throws SQLException; - - public java.util.Map getTypeMap() throws SQLException - { - return typemap; - } - - - public void setTypeMap(java.util.Map map) throws SQLException - { - typemap = map; - } - - /* - * This overides the standard internal getObject method so that we can - * check the jdbc2 type map first - */ - public Object getObject(String type, String value) throws SQLException - { - if (typemap != null) - { - SQLData d = (SQLData) typemap.get(type); - if (d != null) - { - // Handle the type (requires SQLInput & SQLOutput classes to be implemented) - throw org.postgresql.Driver.notImplemented(); - } - } - - // Default to the original method - return super.getObject(type, value); - } - - - //Because the get/setLogStream methods are deprecated in JDBC2 - //we use the get/setLogWriter methods here for JDBC2 by overriding - //the base version of this method - protected void enableDriverManagerLogging() - { - if (DriverManager.getLogWriter() == null) - { - DriverManager.setLogWriter(new PrintWriter(System.out)); - } - } - - - /* - * This implemetation uses the jdbc2Types array to support the jdbc2 - * datatypes. Basically jdbc1 and jdbc2 are the same, except that - * jdbc2 adds the Array types. - */ - public int getSQLType(String pgTypeName) - { - int sqlType = Types.OTHER; // default value - for (int i = 0;i < jdbc2Types.length;i++) - { - if (pgTypeName.equals(jdbc2Types[i])) - { - sqlType = jdbc2Typei[i]; - break; - } - } - return sqlType; - } - - /* - * This table holds the org.postgresql names for the types supported. - * Any types that map to Types.OTHER (eg POINT) don't go into this table. - * They default automatically to Types.OTHER - * - * Note: This must be in the same order as below. - * - * Tip: keep these grouped together by the Types. value - */ - private static final String jdbc2Types[] = { - "int2", - "int4", "oid", - "int8", - "cash", "money", - "numeric", - "float4", - "float8", - "bpchar", "char", "char2", "char4", "char8", "char16", - "varchar", "text", "name", "filename", - "bytea", - "bool", - "bit", - "date", - "time", - "abstime", "timestamp", "timestamptz", - "_bool", "_char", "_int2", "_int4", "_text", - "_oid", "_varchar", "_int8", "_float4", "_float8", - "_abstime", "_date", "_time", "_timestamp", "_numeric", - "_bytea" - }; - - /* - * This table holds the JDBC type for each entry above. - * - * Note: This must be in the same order as above - * - * Tip: keep these grouped together by the Types. value - */ - private static final int jdbc2Typei[] = { - Types.SMALLINT, - Types.INTEGER, Types.INTEGER, - Types.BIGINT, - Types.DOUBLE, Types.DOUBLE, - Types.NUMERIC, - Types.REAL, - Types.DOUBLE, - Types.CHAR, Types.CHAR, Types.CHAR, Types.CHAR, Types.CHAR, Types.CHAR, - Types.VARCHAR, Types.VARCHAR, Types.VARCHAR, Types.VARCHAR, - Types.BINARY, - Types.BIT, - Types.BIT, - Types.DATE, - Types.TIME, - Types.TIMESTAMP, Types.TIMESTAMP, Types.TIMESTAMP, - Types.ARRAY, Types.ARRAY, Types.ARRAY, Types.ARRAY, Types.ARRAY, - Types.ARRAY, Types.ARRAY, Types.ARRAY, Types.ARRAY, Types.ARRAY, - Types.ARRAY, Types.ARRAY, Types.ARRAY, Types.ARRAY, Types.ARRAY, - Types.ARRAY - }; - - - - -} - - diff --git a/src/interfaces/jdbc/org/postgresql/jdbc2/AbstractJdbc2DatabaseMetaData.java b/src/interfaces/jdbc/org/postgresql/jdbc2/AbstractJdbc2DatabaseMetaData.java deleted file mode 100644 index d3f7e1253dd..00000000000 --- a/src/interfaces/jdbc/org/postgresql/jdbc2/AbstractJdbc2DatabaseMetaData.java +++ /dev/null @@ -1,144 +0,0 @@ -package org.postgresql.jdbc2; - -import java.sql.SQLException; - -public abstract class AbstractJdbc2DatabaseMetaData extends org.postgresql.jdbc1.AbstractJdbc1DatabaseMetaData -{ - - public AbstractJdbc2DatabaseMetaData(AbstractJdbc2Connection conn) - { - super(conn); - } - - - - // ** JDBC 2 Extensions ** - - /* - * Does the database support the given result set type? - * - * @param type - defined in java.sql.ResultSet - * @return true if so; false otherwise - * @exception SQLException - if a database access error occurs - */ - public boolean supportsResultSetType(int type) throws SQLException - { - // The only type we don't support - return type != java.sql.ResultSet.TYPE_SCROLL_SENSITIVE; - } - - - /* - * Does the database support the concurrency type in combination - * with the given result set type? - * - * @param type - defined in java.sql.ResultSet - * @param concurrency - type defined in java.sql.ResultSet - * @return true if so; false otherwise - * @exception SQLException - if a database access error occurs - */ - public boolean supportsResultSetConcurrency(int type, int concurrency) throws SQLException - { - // These combinations are not supported! - if (type == java.sql.ResultSet.TYPE_SCROLL_SENSITIVE) - return false; - - // We do support Updateable ResultSets - if (concurrency == java.sql.ResultSet.CONCUR_UPDATABLE) - return true; - - // Everything else we do - return true; - } - - - /* lots of unsupported stuff... */ - public boolean ownUpdatesAreVisible(int type) throws SQLException - { - return true; - } - - public boolean ownDeletesAreVisible(int type) throws SQLException - { - return true; - } - - public boolean ownInsertsAreVisible(int type) throws SQLException - { - // indicates that - return true; - } - - public boolean othersUpdatesAreVisible(int type) throws SQLException - { - return false; - } - - public boolean othersDeletesAreVisible(int i) throws SQLException - { - return false; - } - - public boolean othersInsertsAreVisible(int type) throws SQLException - { - return false; - } - - public boolean updatesAreDetected(int type) throws SQLException - { - return false; - } - - public boolean deletesAreDetected(int i) throws SQLException - { - return false; - } - - public boolean insertsAreDetected(int type) throws SQLException - { - return false; - } - - /* - * Indicates whether the driver supports batch updates. - */ - public boolean supportsBatchUpdates() throws SQLException - { - return true; - } - - /* - * Return user defined types in a schema - */ - public java.sql.ResultSet getUDTs(String catalog, - String schemaPattern, - String typeNamePattern, - int[] types - ) throws SQLException - { - throw org.postgresql.Driver.notImplemented(); - } - - - /* - * Retrieves the connection that produced this metadata object. - * - * @return the connection that produced this metadata object - */ - public java.sql.Connection getConnection() throws SQLException - { - return (java.sql.Connection)connection; - } - - /* I don't find these in the spec!?! */ - - public boolean rowChangesAreDetected(int type) throws SQLException - { - return false; - } - - public boolean rowChangesAreVisible(int type) throws SQLException - { - return false; - } -} diff --git a/src/interfaces/jdbc/org/postgresql/jdbc2/AbstractJdbc2ResultSet.java b/src/interfaces/jdbc/org/postgresql/jdbc2/AbstractJdbc2ResultSet.java deleted file mode 100644 index 37d7f9cf072..00000000000 --- a/src/interfaces/jdbc/org/postgresql/jdbc2/AbstractJdbc2ResultSet.java +++ /dev/null @@ -1,1548 +0,0 @@ -/*------------------------------------------------------------------------- - * - * AbstractJdbc2ResultSet.java - * This class defines methods of the jdbc2 specification. This class - * extends org.postgresql.jdbc1.AbstractJdbc1ResultSet which provides the - * jdbc1 methods. The real Statement class (for jdbc2) is - * org.postgresql.jdbc2.Jdbc2ResultSet - * - * Copyright (c) 2003, PostgreSQL Global Development Group - * - * IDENTIFICATION - * $PostgreSQL: pgsql/src/interfaces/jdbc/org/postgresql/jdbc2/AbstractJdbc2ResultSet.java,v 1.28 2003/12/12 18:34:14 davec Exp $ - * - *------------------------------------------------------------------------- - */ -package org.postgresql.jdbc2; - -import java.io.CharArrayReader; -import java.io.InputStream; -import java.io.IOException; -import java.math.BigDecimal; -import java.sql.*; -import java.util.Enumeration; -import java.util.Hashtable; -import java.util.Iterator; -import java.util.StringTokenizer; -import java.util.Vector; -import org.postgresql.Driver; -import org.postgresql.core.BaseStatement; -import org.postgresql.core.Field; -import org.postgresql.core.Encoding; -import org.postgresql.util.PSQLException; -import org.postgresql.util.PSQLState; - - -public abstract class AbstractJdbc2ResultSet extends org.postgresql.jdbc1.AbstractJdbc1ResultSet -{ - - //needed for updateable result set support - protected boolean updateable = false; - protected boolean doingUpdates = false; - protected boolean onInsertRow = false; - protected Hashtable updateValues = new Hashtable(); - private boolean usingOID = false; // are we using the OID for the primary key? - private Vector primaryKeys; // list of primary keys - private int numKeys = 0; - private boolean singleTable = false; - protected String tableName = null; - protected PreparedStatement updateStatement = null; - protected PreparedStatement insertStatement = null; - protected PreparedStatement deleteStatement = null; - private PreparedStatement selectStatement = null; - - - public AbstractJdbc2ResultSet(BaseStatement statement, Field[] fields, Vector tuples, String status, int updateCount, long insertOID, boolean binaryCursor) - { - super (statement, fields, tuples, status, updateCount, insertOID, binaryCursor); - } - - public java.net.URL getURL(int columnIndex) throws SQLException - { - return null; - } - - - public java.net.URL getURL(String columnName) throws SQLException - { - return null; - } - - - /* - * Get the value of a column in the current row as a Java object - * - * <p>This method will return the value of the given column as a - * Java object. The type of the Java object will be the default - * Java Object type corresponding to the column's SQL type, following - * the mapping specified in the JDBC specification. - * - * <p>This method may also be used to read database specific abstract - * data types. - * - * @param columnIndex the first column is 1, the second is 2... - * @return a Object holding the column value - * @exception SQLException if a database access error occurs - */ - public Object getObject(int columnIndex) throws SQLException - { - Field field; - - checkResultSet( columnIndex ); - - wasNullFlag = (this_row[columnIndex - 1] == null); - if (wasNullFlag) - return null; - - field = fields[columnIndex - 1]; - - // some fields can be null, mainly from those returned by MetaData methods - if (field == null) - { - wasNullFlag = true; - return null; - } - - switch (field.getSQLType()) - { - case Types.BIT: - return getBoolean(columnIndex) ? Boolean.TRUE : Boolean.FALSE; - - case Types.SMALLINT: - return new Short(getShort(columnIndex)); - - case Types.INTEGER: - return new Integer(getInt(columnIndex)); - - case Types.BIGINT: - return new Long(getLong(columnIndex)); - - case Types.NUMERIC: - return getBigDecimal - (columnIndex, (field.getMod() == -1) ? -1 : ((field.getMod() - 4) & 0xffff)); - - case Types.REAL: - return new Float(getFloat(columnIndex)); - - case Types.DOUBLE: - return new Double(getDouble(columnIndex)); - - case Types.CHAR: - case Types.VARCHAR: - return getString(columnIndex); - - case Types.DATE: - return getDate(columnIndex); - - case Types.TIME: - return getTime(columnIndex); - - case Types.TIMESTAMP: - return getTimestamp(columnIndex); - - case Types.BINARY: - case Types.VARBINARY: - return getBytes(columnIndex); - - case Types.ARRAY: - return getArray(columnIndex); - - default: - String type = field.getPGType(); - - // if the backend doesn't know the type then coerce to String - if (type.equals("unknown")) - { - return getString(columnIndex); - } - // Specialized support for ref cursors is neater. - else if (type.equals("refcursor")) - { - String cursorName = getString(columnIndex); - return statement.createRefCursorResultSet(cursorName); - } - else - { - return connection.getObject(field.getPGType(), getString(columnIndex)); - } - } - } - - - public boolean absolute(int index) throws SQLException - { - // index is 1-based, but internally we use 0-based indices - int internalIndex; - - if (index == 0) - throw new SQLException("Cannot move to index of 0"); - - final int rows_size = rows.size(); - - //if index<0, count from the end of the result set, but check - //to be sure that it is not beyond the first index - if (index < 0) - { - if (index >= -rows_size) - internalIndex = rows_size + index; - else - { - beforeFirst(); - return false; - } - } - else - { - //must be the case that index>0, - //find the correct place, assuming that - //the index is not too large - if (index <= rows_size) - internalIndex = index - 1; - else - { - afterLast(); - return false; - } - } - - current_row = internalIndex; - this_row = (byte[][]) rows.elementAt(internalIndex); - - rowBuffer = new byte[this_row.length][]; - System.arraycopy(this_row, 0, rowBuffer, 0, this_row.length); - - return true; - } - - - public void afterLast() throws SQLException - { - final int rows_size = rows.size(); - if (rows_size > 0) - current_row = rows_size; - } - - - public void beforeFirst() throws SQLException - { - if (rows.size() > 0) - current_row = -1; - } - - - public boolean first() throws SQLException - { - if (rows.size() <= 0) - return false; - - onInsertRow = false; - current_row = 0; - this_row = (byte[][]) rows.elementAt(current_row); - - rowBuffer = new byte[this_row.length][]; - System.arraycopy(this_row, 0, rowBuffer, 0, this_row.length); - - return true; - } - - - public java.sql.Array getArray(String colName) throws SQLException - { - return getArray(findColumn(colName)); - } - - - public java.sql.Array getArray(int i) throws SQLException - { - checkResultSet( i ); - - wasNullFlag = (this_row[i - 1] == null); - if (wasNullFlag) - return null; - - if (i < 1 || i > fields.length) - throw new PSQLException("postgresql.res.colrange", PSQLState.INVALID_PARAMETER_VALUE); - return (java.sql.Array) new org.postgresql.jdbc2.Array( connection, i, fields[i - 1], this ); - } - - - public java.math.BigDecimal getBigDecimal(int columnIndex) throws SQLException - { - return getBigDecimal(columnIndex, -1); - } - - - public java.math.BigDecimal getBigDecimal(String columnName) throws SQLException - { - return getBigDecimal(findColumn(columnName)); - } - - - public Blob getBlob(String columnName) throws SQLException - { - return getBlob(findColumn(columnName)); - } - - - public abstract Blob getBlob(int i) throws SQLException; - - - public java.io.Reader getCharacterStream(String columnName) throws SQLException - { - return getCharacterStream(findColumn(columnName)); - } - - - public java.io.Reader getCharacterStream(int i) throws SQLException - { - checkResultSet( i ); - wasNullFlag = (this_row[i - 1] == null); - if (wasNullFlag) - return null; - - if (((AbstractJdbc2Connection) connection).haveMinimumCompatibleVersion("7.2")) - { - //Version 7.2 supports AsciiStream for all the PG text types - //As the spec/javadoc for this method indicate this is to be used for - //large text values (i.e. LONGVARCHAR) PG doesn't have a separate - //long string datatype, but with toast the text datatype is capable of - //handling very large values. Thus the implementation ends up calling - //getString() since there is no current way to stream the value from the server - return new CharArrayReader(getString(i).toCharArray()); - } - else - { - // In 7.1 Handle as BLOBS so return the LargeObject input stream - Encoding encoding = connection.getEncoding(); - InputStream input = getBinaryStream(i); - return encoding.getDecodingReader(input); - } - } - - - public Clob getClob(String columnName) throws SQLException - { - return getClob(findColumn(columnName)); - } - - - public abstract Clob getClob(int i) throws SQLException; - - - public int getConcurrency() throws SQLException - { - if (statement == null) - return java.sql.ResultSet.CONCUR_READ_ONLY; - return statement.getResultSetConcurrency(); - } - - - public java.sql.Date getDate(int i, java.util.Calendar cal) throws SQLException - { - // If I read the specs, this should use cal only if we don't - // store the timezone, and if we do, then act just like getDate()? - // for now... - return getDate(i); - } - - - public Time getTime(int i, java.util.Calendar cal) throws SQLException - { - // If I read the specs, this should use cal only if we don't - // store the timezone, and if we do, then act just like getTime()? - // for now... - return getTime(i); - } - - - public Timestamp getTimestamp(int i, java.util.Calendar cal) throws SQLException - { - // If I read the specs, this should use cal only if we don't - // store the timezone, and if we do, then act just like getDate()? - // for now... - return getTimestamp(i); - } - - - public java.sql.Date getDate(String c, java.util.Calendar cal) throws SQLException - { - return getDate(findColumn(c), cal); - } - - - public Time getTime(String c, java.util.Calendar cal) throws SQLException - { - return getTime(findColumn(c), cal); - } - - - public Timestamp getTimestamp(String c, java.util.Calendar cal) throws SQLException - { - return getTimestamp(findColumn(c), cal); - } - - - public int getFetchDirection() throws SQLException - { - //PostgreSQL normally sends rows first->last - return java.sql.ResultSet.FETCH_FORWARD; - } - - - public Object getObject(String columnName, java.util.Map map) throws SQLException - { - return getObject(findColumn(columnName), map); - } - - - /* - * This checks against map for the type of column i, and if found returns - * an object based on that mapping. The class must implement the SQLData - * interface. - */ - public Object getObject(int i, java.util.Map map) throws SQLException - { - throw org.postgresql.Driver.notImplemented(); - } - - - public Ref getRef(String columnName) throws SQLException - { - return getRef(findColumn(columnName)); - } - - - public Ref getRef(int i) throws SQLException - { - //The backend doesn't yet have SQL3 REF types - throw new PSQLException("postgresql.psqlnotimp", PSQLState.NOT_IMPLEMENTED); - } - - - public int getRow() throws SQLException - { - final int rows_size = rows.size(); - - if (current_row < 0 || current_row >= rows_size) - return 0; - - return current_row + 1; - } - - - // This one needs some thought, as not all ResultSets come from a statement - public Statement getStatement() throws SQLException - { - return (Statement) statement; - } - - - public int getType() throws SQLException - { - // This implementation allows scrolling but is not able to - // see any changes. Sub-classes may overide this to return a more - // meaningful result. - return java.sql.ResultSet.TYPE_SCROLL_INSENSITIVE; - } - - - public boolean isAfterLast() throws SQLException - { - final int rows_size = rows.size(); - return (current_row >= rows_size && rows_size > 0); - } - - - public boolean isBeforeFirst() throws SQLException - { - return (current_row < 0 && rows.size() > 0); - } - - - public boolean isFirst() throws SQLException - { - return (current_row == 0 && rows.size() >= 0); - } - - - public boolean isLast() throws SQLException - { - final int rows_size = rows.size(); - return (current_row == rows_size - 1 && rows_size > 0); - } - - - public boolean last() throws SQLException - { - final int rows_size = rows.size(); - if (rows_size <= 0) - return false; - - current_row = rows_size - 1; - this_row = (byte[][]) rows.elementAt(current_row); - - rowBuffer = new byte[this_row.length][]; - System.arraycopy(this_row, 0, rowBuffer, 0, this_row.length); - - return true; - } - - - public boolean previous() throws SQLException - { - if (--current_row < 0) - return false; - this_row = (byte[][]) rows.elementAt(current_row); - rowBuffer = new byte[this_row.length][]; - System.arraycopy(this_row, 0, rowBuffer, 0, this_row.length); - return true; - } - - - public boolean relative(int rows) throws SQLException - { - //have to add 1 since absolute expects a 1-based index - return absolute(current_row + 1 + rows); - } - - - public void setFetchDirection(int direction) throws SQLException - { - throw new PSQLException("postgresql.psqlnotimp", PSQLState.NOT_IMPLEMENTED); - } - - - public synchronized void cancelRowUpdates() - throws SQLException - { - if (doingUpdates) - { - doingUpdates = false; - - clearRowBuffer(true); - } - } - - - public synchronized void deleteRow() - throws SQLException - { - if ( !isUpdateable() ) - { - throw new PSQLException( "postgresql.updateable.notupdateable" ); - } - - if (onInsertRow) - { - throw new PSQLException( "postgresql.updateable.oninsertrow" ); - } - - if (rows.size() == 0) - { - throw new PSQLException( "postgresql.updateable.emptydelete" ); - } - if (isBeforeFirst()) - { - throw new PSQLException( "postgresql.updateable.beforestartdelete" ); - } - if (isAfterLast()) - { - throw new PSQLException( "postgresql.updateable.afterlastdelete" ); - } - - - int numKeys = primaryKeys.size(); - if ( deleteStatement == null ) - { - - - StringBuffer deleteSQL = new StringBuffer("DELETE FROM " ).append(tableName).append(" where " ); - - for ( int i = 0; i < numKeys; i++ ) - { - deleteSQL.append( ((PrimaryKey) primaryKeys.get(i)).name ).append( " = ? " ); - if ( i < numKeys - 1 ) - { - deleteSQL.append( " and " ); - } - } - - deleteStatement = ((java.sql.Connection) connection).prepareStatement(deleteSQL.toString()); - } - deleteStatement.clearParameters(); - - for ( int i = 0; i < numKeys; i++ ) - { - deleteStatement.setObject(i + 1, ((PrimaryKey) primaryKeys.get(i)).getValue()); - } - - - deleteStatement.executeUpdate(); - - rows.removeElementAt(current_row); - } - - - public synchronized void insertRow() - throws SQLException - { - if ( !isUpdateable() ) - { - throw new PSQLException( "postgresql.updateable.notupdateable" ); - } - - if (!onInsertRow) - { - throw new PSQLException( "postgresql.updateable.notoninsertrow" ); - } - else - { - - // loop through the keys in the insertTable and create the sql statement - // we have to create the sql every time since the user could insert different - // columns each time - - StringBuffer insertSQL = new StringBuffer("INSERT INTO ").append(tableName).append(" ("); - StringBuffer paramSQL = new StringBuffer(") values (" ); - - Enumeration columnNames = updateValues.keys(); - int numColumns = updateValues.size(); - - for ( int i = 0; columnNames.hasMoreElements(); i++ ) - { - String columnName = (String) columnNames.nextElement(); - - insertSQL.append( columnName ); - if ( i < numColumns - 1 ) - { - insertSQL.append(", "); - paramSQL.append("?,"); - } - else - { - paramSQL.append("?)"); - } - - } - - insertSQL.append(paramSQL.toString()); - insertStatement = ((java.sql.Connection) connection).prepareStatement(insertSQL.toString()); - - Enumeration keys = updateValues.keys(); - - for ( int i = 1; keys.hasMoreElements(); i++) - { - String key = (String) keys.nextElement(); - Object o = updateValues.get(key); - if (o instanceof NullObject) - insertStatement.setNull(i,java.sql.Types.NULL); - else - insertStatement.setObject(i, o); - } - - insertStatement.executeUpdate(); - - if ( usingOID ) - { - // we have to get the last inserted OID and put it in the resultset - - long insertedOID = ((AbstractJdbc2Statement) insertStatement).getLastOID(); - - updateValues.put("oid", new Long(insertedOID) ); - - } - - // update the underlying row to the new inserted data - updateRowBuffer(); - - rows.addElement(rowBuffer); - - // we should now reflect the current data in this_row - // that way getXXX will get the newly inserted data - this_row = rowBuffer; - - // need to clear this in case of another insert - clearRowBuffer(false); - - - } - } - - - public synchronized void moveToCurrentRow() - throws SQLException - { - if (!updateable) - { - throw new PSQLException( "postgresql.updateable.notupdateable" ); - } - - if (current_row < 0) { - this_row = null; - rowBuffer = null; - } else { - this_row = (byte[][]) rows.elementAt(current_row); - - rowBuffer = new byte[this_row.length][]; - System.arraycopy(this_row, 0, rowBuffer, 0, this_row.length); - } - - onInsertRow = false; - doingUpdates = false; - } - - - public synchronized void moveToInsertRow() - throws SQLException - { - if ( !isUpdateable() ) - { - throw new PSQLException( "postgresql.updateable.notupdateable" ); - } - - if (insertStatement != null) - { - insertStatement = null; - } - - - // make sure the underlying data is null - clearRowBuffer(false); - - onInsertRow = true; - doingUpdates = false; - - } - - - private synchronized void clearRowBuffer(boolean copyCurrentRow) - throws SQLException - { - // rowBuffer is the temporary storage for the row - rowBuffer = new byte[fields.length][]; - - // inserts want an empty array while updates want a copy of the current row - if (copyCurrentRow) { - System.arraycopy(this_row, 0, rowBuffer, 0, this_row.length); - } - - // clear the updateValues hashTable for the next set of updates - updateValues.clear(); - - } - - - public boolean rowDeleted() throws SQLException - { - // only sub-classes implement CONCURuPDATEABLE - throw Driver.notImplemented(); - } - - - public boolean rowInserted() throws SQLException - { - // only sub-classes implement CONCURuPDATEABLE - throw Driver.notImplemented(); - } - |