]> granicus.if.org Git - postgresql/commitdiff
Add missing files.
authorBruce Momjian <bruce@momjian.us>
Thu, 6 Sep 2001 03:58:59 +0000 (03:58 +0000)
committerBruce Momjian <bruce@momjian.us>
Thu, 6 Sep 2001 03:58:59 +0000 (03:58 +0000)
src/interfaces/jdbc/org/postgresql/core/QueryExecutor.java [new file with mode: 0644]
src/interfaces/jdbc/org/postgresql/jdbc2/PBatchUpdateException.java [new file with mode: 0644]

diff --git a/src/interfaces/jdbc/org/postgresql/core/QueryExecutor.java b/src/interfaces/jdbc/org/postgresql/core/QueryExecutor.java
new file mode 100644 (file)
index 0000000..e45dffc
--- /dev/null
@@ -0,0 +1,187 @@
+
+package org.postgresql.core;
+
+import java.util.Vector;
+import java.io.IOException;
+import java.sql.*;
+import org.postgresql.*;
+import org.postgresql.util.PSQLException;
+
+/**
+ * Executes a query on the backend.
+ *
+ * <p>The lifetime of a QueryExecutor object is from sending the query
+ * until the response has been received from the backend.
+ *
+ * $Id: QueryExecutor.java,v 1.1 2001/09/06 03:58:59 momjian Exp $
+ */
+
+public class QueryExecutor {
+
+    private final String sql;
+    private final java.sql.Statement statement;
+    private final PG_Stream pg_stream;
+    private final org.postgresql.Connection connection;
+
+    public QueryExecutor(String sql,
+                        java.sql.Statement statement,
+                        PG_Stream pg_stream,
+                        org.postgresql.Connection connection)
+       throws SQLException
+    {
+       this.sql = sql;
+       this.statement = statement;
+       this.pg_stream = pg_stream;
+       this.connection = connection;
+
+       if (statement != null)
+           maxRows = statement.getMaxRows();
+       else
+           maxRows = 0;
+    }
+
+    private Field[] fields = null;
+    private Vector tuples = new Vector();
+    private String status = null;
+    private int update_count = 1;
+    private int insert_oid = 0;
+    private int maxRows;
+
+    /**
+     * Execute a query on the backend.
+     */
+    public java.sql.ResultSet execute() throws SQLException {
+
+       int fqp = 0;
+       boolean hfr = false;
+
+       synchronized(pg_stream) {
+
+           sendQuery(sql);
+
+           while (!hfr || fqp > 0) {
+               int c = pg_stream.ReceiveChar();
+
+               switch (c)
+                   {
+                   case 'A':   // Asynchronous Notify
+                       int pid = pg_stream.ReceiveInteger(4);
+                       String msg = pg_stream.ReceiveString(connection.getEncoding());
+                       break;
+                   case 'B':   // Binary Data Transfer
+                       receiveTuple(true);
+                       break;
+                   case 'C':   // Command Status
+                       receiveCommandStatus();
+
+                       if (fields != null)
+                           hfr = true;
+                       else {
+                           sendQuery(" ");
+                           fqp++;
+                       }
+                       break;
+                   case 'D':   // Text Data Transfer
+                       receiveTuple(false);
+                       break;
+                   case 'E':   // Error Message
+                       throw new SQLException(pg_stream.ReceiveString(connection.getEncoding()));
+                   case 'I':   // Empty Query
+                       int t = pg_stream.ReceiveChar();
+                       if (t != 0)
+                           throw new PSQLException("postgresql.con.garbled");
+
+                       if (fqp > 0)
+                           fqp--;
+                       if (fqp == 0)
+                           hfr = true;
+                       break;
+                   case 'N':   // Error Notification
+                       connection.addWarning(pg_stream.ReceiveString(connection.getEncoding()));
+                       break;
+                   case 'P':   // Portal Name
+                       String pname = pg_stream.ReceiveString(connection.getEncoding());
+                       break;
+                   case 'T':   // MetaData Field Description
+                       receiveFields();
+                       break;
+                   case 'Z':       // backend ready for query, ignore for now :-)
+                       break;
+                   default:
+                       throw new PSQLException("postgresql.con.type",
+                                               new Character((char) c));
+                   }
+           }
+
+           return connection.getResultSet(connection, statement, fields, tuples, status, update_count, insert_oid);
+       }
+    }
+
+    /**
+     * Send a query to the backend.
+     */
+    private void sendQuery(String query) throws SQLException {
+       try {
+           pg_stream.SendChar('Q');
+           pg_stream.Send(connection.getEncoding().encode(query));
+           pg_stream.SendChar(0);
+           pg_stream.flush();
+
+       } catch (IOException e) {
+           throw new PSQLException("postgresql.con.ioerror", e);
+       }
+    }
+
+    /**
+     * Receive a tuple from the backend.
+     *
+     * @param isBinary set if the tuple should be treated as binary data
+     */
+    private void receiveTuple(boolean isBinary) throws SQLException {
+       if (fields == null)
+           throw new PSQLException("postgresql.con.tuple");
+       Object tuple = pg_stream.ReceiveTuple(fields.length, isBinary);
+       if (maxRows == 0 || tuples.size() < maxRows)
+           tuples.addElement(tuple);
+    }
+
+    /**
+     * Receive command status from the backend.
+     */
+    private void receiveCommandStatus() throws SQLException {
+
+       status = pg_stream.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 = Integer.parseInt(status.substring(1 + status.indexOf(' '),
+                                                              status.lastIndexOf(' ')));
+           }
+       } catch (NumberFormatException nfe) {
+           throw new PSQLException("postgresql.con.fathom", status);
+       }
+    }
+
+    /**
+     * Receive the field descriptions from the back end.
+     */
+    private void receiveFields() throws SQLException {
+       if (fields != null)
+           throw new PSQLException("postgresql.con.multres");
+
+       int size = pg_stream.ReceiveIntegerR(2);
+       fields = new Field[size];
+
+       for (int i = 0; i < fields.length; i++) {
+           String typeName = pg_stream.ReceiveString(connection.getEncoding());
+           int typeOid = pg_stream.ReceiveIntegerR(4);
+           int typeLength = pg_stream.ReceiveIntegerR(2);
+           int typeModifier = pg_stream.ReceiveIntegerR(4);
+           fields[i] = new Field(connection, typeName, typeOid, typeLength, typeModifier);
+       }
+    }
+}
diff --git a/src/interfaces/jdbc/org/postgresql/jdbc2/PBatchUpdateException.java b/src/interfaces/jdbc/org/postgresql/jdbc2/PBatchUpdateException.java
new file mode 100644 (file)
index 0000000..2f9d8ee
--- /dev/null
@@ -0,0 +1,46 @@
+package org.postgresql.jdbc2;
+
+import org.postgresql.util.*;
+import java.sql.*;
+
+/**
+ * This class extends java.sql.BatchUpdateException, and provides our 
+ * internationalisation handling.
+ */
+class PBatchUpdateException extends java.sql.BatchUpdateException {
+
+       private String message;
+
+       public PBatchUpdateException(
+               String error, Object arg1, Object arg2, int[] updateCounts ) {
+
+               super(updateCounts);
+
+               Object[] argv = new Object[2];
+               argv[0] = arg1;
+               argv[1] = arg2;
+               translate(error,argv);
+       }
+
+       private void translate(String error, Object[] args) {
+               message = MessageTranslator.translate(error,args);
+       }
+
+       // Overides Throwable
+       public String getLocalizedMessage()
+       {
+               return message;
+       }
+
+    // Overides Throwable
+       public String getMessage()
+       {
+               return message;
+       }
+
+       // Overides Object
+       public String toString()
+       {
+           return message;
+       }
+}