1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 40 41 42 43 44 45 46 47 48 49 50 51 52 53 54 55 56 57 58 59 60 61 62 63 64 65 66 67 68 69 70 71 72 73 74 75 76 77 78 79 80 81 82 83 84 85 86 87 88 89 90 91 92 93 94 95 96 97 98 99 100 101 102 103 104 105 106 107 108 109 110 111 112 113 114 115 116 117 118 119 120 121 122 123 124 125 126 127 128 129 130 131 132 133 134 135 136 137 138 139 140 141 142 143 144 145 146 147 148 149 150 151 152 153 154 155 156 157 158 159 160 161 162 163 164 165 166 167 168 169 170 171 172 173 174 175 176 177 178 179 180 181
|
/*-------------------------------------------------------------------------
*
* Copyright (c) 2004-2008, PostgreSQL Global Development Group
* Copyright (c) 2004, Open Cloud Limited.
*
* IDENTIFICATION
* $PostgreSQL: pgjdbc/org/postgresql/core/v2/SimpleParameterList.java,v 1.11 2008/01/08 06:56:27 jurka Exp $
*
*-------------------------------------------------------------------------
*/
package org.postgresql.core.v2;
import org.postgresql.core.*;
import java.io.InputStream;
import java.io.Writer;
import java.io.IOException;
import java.sql.SQLException;
import java.util.Arrays;
import org.postgresql.util.PSQLException;
import org.postgresql.util.PSQLState;
import org.postgresql.util.StreamWrapper;
import org.postgresql.util.GT;
/**
* Parameter list for query parameters in the V2 protocol.
*
* @author Oliver Jowett (oliver@opencloud.com)
*/
class SimpleParameterList implements ParameterList {
SimpleParameterList(int paramCount, boolean useEStringSyntax) {
this.paramValues = new Object[paramCount];
this.useEStringSyntax = useEStringSyntax;
}
public void registerOutParameter(int index, int sqlType ){};
public void registerOutParameter(int index, int sqlType, int precision ){};
public int getInParameterCount() {
return paramValues.length;
}
public int getParameterCount()
{
return paramValues.length;
}
public int getOutParameterCount()
{
return 1;
}
public int[] getTypeOIDs() {
return null;
}
public void setIntParameter(int index, int value) throws SQLException {
setLiteralParameter(index, "" + value, Oid.INT4);
}
public void setLiteralParameter(int index, String value, int oid) throws SQLException {
if (index < 1 || index > paramValues.length)
throw new PSQLException(GT.tr("The column index is out of range: {0}, number of columns: {1}.", new Object[]{new Integer(index), new Integer(paramValues.length)}), PSQLState.INVALID_PARAMETER_VALUE );
paramValues[index - 1] = value;
}
public void setStringParameter(int index, String value, int oid) throws SQLException {
StringBuffer sbuf = new StringBuffer(2 + value.length() * 11 / 10); // Add 10% for escaping.
if (useEStringSyntax)
sbuf.append(' ').append('E');
sbuf.append('\'');
Utils.appendEscapedLiteral(sbuf, value, false);
sbuf.append('\'');
setLiteralParameter(index, sbuf.toString(), oid);
}
public void setBytea(int index, byte[] data, int offset, int length) throws SQLException {
if (index < 1 || index > paramValues.length)
throw new PSQLException(GT.tr("The column index is out of range: {0}, number of columns: {1}.", new Object[]{new Integer(index), new Integer(paramValues.length)}), PSQLState.INVALID_PARAMETER_VALUE );
paramValues[index - 1] = new StreamWrapper(data, offset, length);
}
public void setBytea(int index, final InputStream stream, final int length) throws SQLException {
if (index < 1 || index > paramValues.length)
throw new PSQLException(GT.tr("The column index is out of range: {0}, number of columns: {1}.", new Object[]{new Integer(index), new Integer(paramValues.length)}), PSQLState.INVALID_PARAMETER_VALUE );
paramValues[index - 1] = new StreamWrapper(stream, length);
}
public void setNull(int index, int oid) throws SQLException {
if (index < 1 || index > paramValues.length)
throw new PSQLException(GT.tr("The column index is out of range: {0}, number of columns: {1}.", new Object[]{new Integer(index), new Integer(paramValues.length)}), PSQLState.INVALID_PARAMETER_VALUE );
paramValues[index - 1] = NULL_OBJECT;
}
public String toString(int index) {
if (index < 1 || index > paramValues.length)
throw new IllegalArgumentException("Parameter index " + index + " out of range");
if (paramValues[index - 1] == null)
return "?";
else if (paramValues[index -1] == NULL_OBJECT)
return "NULL";
else
return paramValues[index -1].toString();
}
/**
* Send a streamable bytea encoded as a text representation with an arbitary encoding.
*/
private void streamBytea(StreamWrapper param, Writer encodingWriter) throws IOException {
// NB: we escape everything in this path, as I don't like assuming
// that byte values 32..127 will make it through the encoding
// unscathed..
InputStream stream = param.getStream();
char[] buffer = new char[] { '\\', '\\', 0, 0, 0 };
if (useEStringSyntax)
{
encodingWriter.write(' ');
encodingWriter.write('E');
}
encodingWriter.write('\'');
for (int remaining = param.getLength(); remaining > 0; --remaining)
{
int nextByte = stream.read();
buffer[2] = (char)( '0' + ((nextByte >> 6) & 3));
buffer[3] = (char)( '0' + ((nextByte >> 3) & 7));
buffer[4] = (char)( '0' + (nextByte & 7));
encodingWriter.write(buffer, 0, 5);
}
encodingWriter.write('\'');
}
void writeV2Value(int index, Writer encodingWriter) throws IOException {
if (paramValues[index - 1] instanceof StreamWrapper)
{
streamBytea((StreamWrapper)paramValues[index - 1], encodingWriter);
}
else
{
encodingWriter.write((String)paramValues[index - 1]);
}
}
void checkAllParametersSet() throws SQLException {
for (int i = 0; i < paramValues.length; i++)
{
if (paramValues[i] == null)
throw new PSQLException(GT.tr("No value specified for parameter {0}.", new Integer(i + 1)), PSQLState.INVALID_PARAMETER_VALUE);
}
}
public ParameterList copy() {
SimpleParameterList newCopy = new SimpleParameterList(paramValues.length, useEStringSyntax);
System.arraycopy(paramValues, 0, newCopy.paramValues, 0, paramValues.length);
return newCopy;
}
public void clear() {
Arrays.fill(paramValues, null);
}
private final Object[] paramValues;
private final boolean useEStringSyntax;
/* Object representing NULL; conveniently, String streams exactly as we want it to. *
* nb: we explicitly say "new String" to avoid interning giving us an object that
* might be the same (by identity) as a String elsewhere.
*/
private final static String NULL_OBJECT = new String("NULL");
}
|