[teiid-commits] teiid SVN: r2904 - in trunk: common-core/src/main/java/org/teiid/core/util and 5 other directories.
teiid-commits at lists.jboss.org
teiid-commits at lists.jboss.org
Sun Feb 13 20:30:07 EST 2011
Author: rareddy
Date: 2011-02-13 20:30:06 -0500 (Sun, 13 Feb 2011)
New Revision: 2904
Modified:
trunk/build/kits/jboss-container/deploy/teiid/teiid-jboss-beans.xml
trunk/common-core/src/main/java/org/teiid/core/util/ObjectConverterUtil.java
trunk/engine/src/main/java/org/teiid/dqp/internal/process/DQPConfiguration.java
trunk/jboss-integration/src/main/java/org/teiid/jboss/deployers/RuntimeEngineDeployer.java
trunk/runtime/src/main/java/org/teiid/odbc/ODBCClientRemote.java
trunk/runtime/src/main/java/org/teiid/odbc/ODBCServerRemote.java
trunk/runtime/src/main/java/org/teiid/odbc/ODBCServerRemoteImpl.java
trunk/runtime/src/main/java/org/teiid/transport/ODBCSocketListener.java
trunk/runtime/src/main/java/org/teiid/transport/PgBackendProtocol.java
trunk/runtime/src/main/java/org/teiid/transport/PgFrontendProtocol.java
trunk/runtime/src/main/resources/org/teiid/runtime/i18n.properties
Log:
TEIID-1163: Adding lob support for ODBC using postges 'bytea' data type. This data type does not support streaming.
Modified: trunk/build/kits/jboss-container/deploy/teiid/teiid-jboss-beans.xml
===================================================================
--- trunk/build/kits/jboss-container/deploy/teiid/teiid-jboss-beans.xml 2011-02-10 19:56:37 UTC (rev 2903)
+++ trunk/build/kits/jboss-container/deploy/teiid/teiid-jboss-beans.xml 2011-02-14 01:30:06 UTC (rev 2904)
@@ -110,6 +110,8 @@
<property name="maxSourceRows">-1</property>
<!-- Indicates if an exception should be thrown if the specified value for Maximum Source Rows is exceeded; only up to the maximum rows will be consumed. -->
<property name="exceptionOnMaxSourceRows">true</property>
+ <!-- Maximum size of lob allowed through ODBC connection in bytes (default 5MB) -->
+ <property name="maxODBCLobSizeAllowed">5242880</property>
</bean>
<!-- JDBC Socket connection properties (SSL see below) -->
Modified: trunk/common-core/src/main/java/org/teiid/core/util/ObjectConverterUtil.java
===================================================================
--- trunk/common-core/src/main/java/org/teiid/core/util/ObjectConverterUtil.java 2011-02-10 19:56:37 UTC (rev 2903)
+++ trunk/common-core/src/main/java/org/teiid/core/util/ObjectConverterUtil.java 2011-02-14 01:30:06 UTC (rev 2904)
@@ -90,16 +90,32 @@
* @throws IOException if a problem occurred reading the stream.
*/
public static byte[] convertToByteArray(final InputStream is, int length) throws IOException {
+ return convertToByteArray(is, length, true);
+ }
+
+ public static byte[] convertToByteArray(final InputStream is, int length, boolean close) throws IOException {
ByteArrayOutputStream out = new ByteArrayOutputStream();
- write(out, is, length);
- return out.toByteArray();
+ write(out, is, length, close);
+ out.close();
+ return out.toByteArray();
}
+
+ public static int write(final OutputStream out, final InputStream is, byte[] l_buffer, int length) throws IOException {
+ return write(out, is, l_buffer, length, true);
+ }
- public static int write(final OutputStream out, final InputStream is, byte[] l_buffer, int length) throws IOException {
+ public static int write(final OutputStream out, final InputStream is, byte[] l_buffer, int length, boolean close) throws IOException {
int writen = 0;
try {
int l_nbytes = 0; // Number of bytes read
- while ((l_nbytes = is.read(l_buffer)) != -1) {
+ int readLength = length;
+ if (length == -1) {
+ readLength = l_buffer.length;
+ }
+ else {
+ readLength = Math.min(length, l_buffer.length);
+ }
+ while ((l_nbytes = is.read(l_buffer, 0, readLength)) != -1) {
if (length != -1 && writen > length - l_nbytes) {
out.write(l_buffer, 0, writen + l_nbytes - length);
break;
@@ -109,16 +125,22 @@
}
return writen;
} finally {
- try {
- is.close();
- } finally {
- out.close();
+ if (close) {
+ try {
+ is.close();
+ } finally {
+ out.close();
+ }
}
}
}
+
+ public static int write(final OutputStream out, final InputStream is, int length) throws IOException {
+ return write(out, is, length, true);
+ }
- public static void write(final OutputStream out, final InputStream is, int length) throws IOException {
- write(out, is, new byte[DEFAULT_READING_SIZE], length); // buffer holding bytes to be transferred
+ public static int write(final OutputStream out, final InputStream is, int length, boolean close) throws IOException {
+ return write(out, is, new byte[DEFAULT_READING_SIZE], length, close); // buffer holding bytes to be transferred
}
public static void write(final Writer out, final Reader is, int length) throws IOException {
Modified: trunk/engine/src/main/java/org/teiid/dqp/internal/process/DQPConfiguration.java
===================================================================
--- trunk/engine/src/main/java/org/teiid/dqp/internal/process/DQPConfiguration.java 2011-02-10 19:56:37 UTC (rev 2903)
+++ trunk/engine/src/main/java/org/teiid/dqp/internal/process/DQPConfiguration.java 2011-02-14 01:30:06 UTC (rev 2904)
@@ -51,6 +51,7 @@
private int maxSourceRows = -1;
private int maxActivePlans = DEFAULT_MAX_ACTIVE_PLANS;
private CacheConfiguration resultsetCacheConfig;
+ private int maxODBCLobSizeAllowed = 5*1024*1024; // 5 MB
@ManagementProperty(description="Max active plans (default 20). Increase this value, and max threads, on highly concurrent systems - but ensure that the underlying pools can handle the increased load without timeouts.")
public int getMaxActivePlans() {
@@ -185,4 +186,13 @@
public void setMaxSourceRows(int maxSourceRows) {
this.maxSourceRows = maxSourceRows;
}
+
+ @ManagementProperty(description="Maximum Lob Size allowed over ODBC (default 5MB)")
+ public int getMaxODBCLobSizeAllowed() {
+ return this.maxODBCLobSizeAllowed;
+ }
+
+ public void setMaxODBCLobSizeAllowed(int lobSize) {
+ this.maxODBCLobSizeAllowed = lobSize;
+ }
}
Modified: trunk/jboss-integration/src/main/java/org/teiid/jboss/deployers/RuntimeEngineDeployer.java
===================================================================
--- trunk/jboss-integration/src/main/java/org/teiid/jboss/deployers/RuntimeEngineDeployer.java 2011-02-10 19:56:37 UTC (rev 2903)
+++ trunk/jboss-integration/src/main/java/org/teiid/jboss/deployers/RuntimeEngineDeployer.java 2011-02-14 01:30:06 UTC (rev 2904)
@@ -192,7 +192,7 @@
if (this.odbcSocketConfiguration.getEnabled()) {
this.vdbRepository.odbcEnabled();
- this.odbcSocket = new ODBCSocketListener(this.odbcSocketConfiguration, this.dqpCore.getBufferManager(), offset);
+ this.odbcSocket = new ODBCSocketListener(this.odbcSocketConfiguration, this.dqpCore.getBufferManager(), offset, getMaxODBCLobSizeAllowed());
LogManager.logInfo(LogConstants.CTX_RUNTIME, IntegrationPlugin.Util.getString("odbc_enabled","Teiid ODBC - SSL=", (this.odbcSocketConfiguration.getSSLConfiguration().isSslEnabled()?"ON":"OFF")+" Host = "+this.odbcSocketConfiguration.getHostAddress().getHostName()+" Port = "+(this.odbcSocketConfiguration.getPortNumber()+offset))); //$NON-NLS-1$ //$NON-NLS-2$ //$NON-NLS-3$ //$NON-NLS-4$ //$NON-NLS-5$ //$NON-NLS-6$
} else {
LogManager.logInfo(LogConstants.CTX_RUNTIME, IntegrationPlugin.Util.getString("odbc_not_enabled")); //$NON-NLS-1$
Modified: trunk/runtime/src/main/java/org/teiid/odbc/ODBCClientRemote.java
===================================================================
--- trunk/runtime/src/main/java/org/teiid/odbc/ODBCClientRemote.java 2011-02-10 19:56:37 UTC (rev 2903)
+++ trunk/runtime/src/main/java/org/teiid/odbc/ODBCClientRemote.java 2011-02-14 01:30:06 UTC (rev 2904)
@@ -79,6 +79,12 @@
void flush();
+ // FunctionCallResponse (B)
+ void functionCallResponse(byte[] data);
+ void functionCallResponse(int data);
+
+ void sslDenied();
+
// unimplemented backend messages
// AuthenticationKerberosV5 (B)
@@ -95,8 +101,6 @@
// CopyInResponse (B)
// CopyOutResponse (B)
- // FunctionCallResponse (B)
-
// NoticeResponse (B)
// NotificationResponse (B)
Modified: trunk/runtime/src/main/java/org/teiid/odbc/ODBCServerRemote.java
===================================================================
--- trunk/runtime/src/main/java/org/teiid/odbc/ODBCServerRemote.java 2011-02-10 19:56:37 UTC (rev 2903)
+++ trunk/runtime/src/main/java/org/teiid/odbc/ODBCServerRemote.java 2011-02-14 01:30:06 UTC (rev 2904)
@@ -56,13 +56,14 @@
void flush();
+ void functionCall(int oid);
+
+ void sslRequest();
+
// unimplemented frontend messages
// CopyData (F & B)
// CopyDone (F & B)
// CopyFail (F)
- // Flush (F)
- // FunctionCall (F)
- // SSLRequest (F)
}
Modified: trunk/runtime/src/main/java/org/teiid/odbc/ODBCServerRemoteImpl.java
===================================================================
--- trunk/runtime/src/main/java/org/teiid/odbc/ODBCServerRemoteImpl.java 2011-02-10 19:56:37 UTC (rev 2903)
+++ trunk/runtime/src/main/java/org/teiid/odbc/ODBCServerRemoteImpl.java 2011-02-14 01:30:06 UTC (rev 2904)
@@ -571,7 +571,18 @@
public void flush() {
this.client.flush();
}
-
+
+ @Override
+ public void functionCall(int oid) {
+ this.client.errorOccurred(RuntimePlugin.Util.getString("lo_not_supported")); //$NON-NLS-1$
+ sync();
+ }
+
+ @Override
+ public void sslRequest() {
+ this.client.sslDenied();
+ }
+
/**
* Represents a PostgreSQL Prepared object.
*/
Modified: trunk/runtime/src/main/java/org/teiid/transport/ODBCSocketListener.java
===================================================================
--- trunk/runtime/src/main/java/org/teiid/transport/ODBCSocketListener.java 2011-02-10 19:56:37 UTC (rev 2903)
+++ trunk/runtime/src/main/java/org/teiid/transport/ODBCSocketListener.java 2011-02-14 01:30:06 UTC (rev 2904)
@@ -32,10 +32,12 @@
public class ODBCSocketListener extends SocketListener {
private ODBCServerRemote.AuthenticationType authType = ODBCServerRemote.AuthenticationType.CLEARTEXT;
+ private int maxLobSize;
- public ODBCSocketListener(SocketConfiguration config, StorageManager storageManager, int portOffset) {
+ public ODBCSocketListener(SocketConfiguration config, StorageManager storageManager, int portOffset, int maxLobSize) {
//the clientserviceregistry isn't actually used by ODBC
super(config, new ClientServiceRegistryImpl(ClientServiceRegistry.Type.ODBC), storageManager, portOffset);
+ this.maxLobSize = maxLobSize;
}
@Override
@@ -49,7 +51,7 @@
pipeline.addLast("ssl", new SslHandler(engine)); //$NON-NLS-1$
}
pipeline.addLast("odbcFrontendProtocol", new PgFrontendProtocol(1 << 20)); //$NON-NLS-1$
- pipeline.addLast("odbcBackendProtocol", new PgBackendProtocol()); //$NON-NLS-1$
+ pipeline.addLast("odbcBackendProtocol", new PgBackendProtocol(maxLobSize)); //$NON-NLS-1$
pipeline.addLast("handler", this); //$NON-NLS-1$
return pipeline;
}
Modified: trunk/runtime/src/main/java/org/teiid/transport/PgBackendProtocol.java
===================================================================
--- trunk/runtime/src/main/java/org/teiid/transport/PgBackendProtocol.java 2011-02-10 19:56:37 UTC (rev 2903)
+++ trunk/runtime/src/main/java/org/teiid/transport/PgBackendProtocol.java 2011-02-14 01:30:06 UTC (rev 2904)
@@ -27,10 +27,13 @@
import java.lang.reflect.InvocationTargetException;
import java.lang.reflect.Method;
import java.nio.charset.Charset;
+import java.sql.Blob;
+import java.sql.Clob;
import java.sql.ParameterMetaData;
import java.sql.ResultSet;
import java.sql.ResultSetMetaData;
import java.sql.SQLException;
+import java.sql.SQLXML;
import java.sql.Types;
import java.util.Properties;
@@ -41,6 +44,8 @@
import org.jboss.netty.channel.ChannelHandlerContext;
import org.jboss.netty.channel.Channels;
import org.jboss.netty.channel.MessageEvent;
+import org.teiid.core.util.ObjectConverterUtil;
+import org.teiid.core.util.ReaderInputStream;
import org.teiid.core.util.ReflectionHelper;
import org.teiid.jdbc.TeiidSQLException;
import org.teiid.logging.LogConstants;
@@ -64,15 +69,16 @@
private static final int PG_TYPE_INT2 = 21;
private static final int PG_TYPE_INT4 = 23;
private static final int PG_TYPE_TEXT = 25;
- private static final int PG_TYPE_OID = 26;
+ //private static final int PG_TYPE_OID = 26;
private static final int PG_TYPE_FLOAT4 = 700;
private static final int PG_TYPE_FLOAT8 = 701;
private static final int PG_TYPE_UNKNOWN = 705;
- private static final int PG_TYPE_TEXTARRAY = 1009;
+ //private static final int PG_TYPE_TEXTARRAY = 1009;
private static final int PG_TYPE_DATE = 1082;
private static final int PG_TYPE_TIME = 1083;
private static final int PG_TYPE_TIMESTAMP_NO_TMZONE = 1114;
private static final int PG_TYPE_NUMERIC = 1700;
+ //private static final int PG_TYPE_LO = 14939;
private DataOutputStream dataOut;
private ByteArrayOutputStream outBuffer;
@@ -82,7 +88,12 @@
private ReflectionHelper clientProxy = new ReflectionHelper(ODBCClientRemote.class);
private ChannelHandlerContext ctx;
private MessageEvent message;
+ private int maxLobSize = (2*1024*1024); // 2 MB
+ public PgBackendProtocol(int maxLobSize) {
+ this.maxLobSize = maxLobSize;
+ }
+
@Override
public void handleDownstream(ChannelHandlerContext ctx, ChannelEvent evt) throws Exception {
if (!(evt instanceof MessageEvent)) {
@@ -210,7 +221,7 @@
if (paramType != null && paramType[i] != 0) {
type = paramType[i];
} else {
- type = PG_TYPE_VARCHAR;
+ type = convertType(meta.getParameterType(i+1));
}
writeInt(type);
}
@@ -244,8 +255,13 @@
ResultSetMetaData meta = rs.getMetaData();
sendRowDescription(meta);
}
+ int columns = rs.getMetaData().getColumnCount();
+ int[] types = new int[columns];
+ for(int i = 0; i < columns; i++) {
+ types[i] = rs.getMetaData().getColumnType(i+1);
+ }
while (rs.next()) {
- sendDataRow(rs);
+ sendDataRow(rs, columns, types);
}
sendCommandComplete(sql, 0);
} catch (SQLException e) {
@@ -331,27 +347,81 @@
sendMessage();
}
- private void sendDataRow(ResultSet rs) throws SQLException, IOException {
- int columns = rs.getMetaData().getColumnCount();
- String[] values = new String[columns];
- for (int i = 0; i < columns; i++) {
- values[i] = rs.getString(i + 1);
- }
+ private void sendDataRow(ResultSet rs, int columns, int[] types) throws SQLException, IOException {
startMessage('D');
writeShort(columns);
- for (String s : values) {
- if (s == null) {
+ for (int i = 0; i < columns; i++) {
+ byte[] bytes = getContent(rs, types[i], i+1);
+ if (bytes == null) {
writeInt(-1);
} else {
- // TODO write Binary data
- byte[] d2 = s.getBytes(this.encoding);
- writeInt(d2.length);
- write(d2);
+ writeInt(bytes.length);
+ write(bytes);
}
}
sendMessage();
}
+ private byte[] getContent(ResultSet rs, int type, int column) throws SQLException, TeiidSQLException, IOException {
+ byte[] bytes = null;
+ switch (type) {
+ case Types.BOOLEAN:
+ case Types.VARCHAR:
+ case Types.CHAR:
+ case Types.SMALLINT:
+ case Types.INTEGER:
+ case Types.BIGINT:
+ case Types.NUMERIC:
+ case Types.DECIMAL:
+ case Types.FLOAT:
+ case Types.REAL:
+ case Types.DOUBLE:
+ case Types.TIME:
+ case Types.DATE:
+ case Types.TIMESTAMP:
+ String value = rs.getString(column);
+ if (value != null) {
+ bytes = value.getBytes(this.encoding);
+ }
+ break;
+
+ case Types.LONGVARCHAR:
+ case Types.CLOB:
+ Clob clob = rs.getClob(column);
+ if (clob != null) {
+ bytes = ObjectConverterUtil.convertToByteArray(new ReaderInputStream(clob.getCharacterStream(), this.encoding), this.maxLobSize);
+ }
+ break;
+
+ case Types.SQLXML:
+ SQLXML xml = rs.getSQLXML(column);
+ if (xml != null) {
+ bytes = ObjectConverterUtil.convertToByteArray(new ReaderInputStream(xml.getCharacterStream(), this.encoding), this.maxLobSize);
+ }
+ break;
+
+ case Types.BINARY:
+ case Types.VARBINARY:
+ case Types.LONGVARBINARY:
+ case Types.BLOB:
+ Blob blob = rs.getBlob(column);
+ if (blob != null) {
+ bytes = toHex(ObjectConverterUtil.convertToByteArray(blob.getBinaryStream(), this.maxLobSize));
+ }
+ break;
+ default:
+ throw new TeiidSQLException("unknown datatype failed to convert");
+ }
+ return bytes;
+ }
+
+ @Override
+ public void sslDenied() {
+ ChannelBuffer buffer = ChannelBuffers.directBuffer(1);
+ buffer.writeByte('N');
+ Channels.write(this.ctx, this.message.getFuture(), buffer, this.message.getRemoteAddress());
+ }
+
private void sendErrorResponse(Throwable t) throws IOException {
trace(t.getMessage());
SQLException e = TeiidSQLException.create(t);
@@ -496,6 +566,35 @@
writeString(value);
sendMessage();
}
+
+ @Override
+ public void functionCallResponse(byte[] data) {
+ try {
+ startMessage('V');
+ if (data == null) {
+ writeInt(-1);
+ }
+ else {
+ writeInt(data.length);
+ write(data);
+ }
+ sendMessage();
+ } catch (IOException e) {
+ terminate(e);
+ }
+ }
+
+ @Override
+ public void functionCallResponse(int data) {
+ try {
+ startMessage('V');
+ writeInt(4);
+ writeInt(data);
+ sendMessage();
+ } catch (IOException e) {
+ terminate(e);
+ }
+ }
private void writeString(String s) throws IOException {
write(s.getBytes(this.encoding));
@@ -543,26 +642,30 @@
LogManager.logTrace(LogConstants.CTX_ODBC, msg);
}
+ /**
+ * Types.ARRAY is not supported
+ */
private static int convertType(final int type) {
switch (type) {
case Types.BOOLEAN:
- return PG_TYPE_BOOL;
+ return PG_TYPE_BOOL;
case Types.VARCHAR:
- return PG_TYPE_VARCHAR;
- case Types.CLOB:
- return PG_TYPE_TEXT;
+ return PG_TYPE_VARCHAR;
case Types.CHAR:
- return PG_TYPE_BPCHAR;
+ return PG_TYPE_BPCHAR;
+ case Types.TINYINT:
case Types.SMALLINT:
- return PG_TYPE_INT2;
+ return PG_TYPE_INT2;
case Types.INTEGER:
- return PG_TYPE_INT4;
+ return PG_TYPE_INT4;
case Types.BIGINT:
- return PG_TYPE_INT8;
+ return PG_TYPE_INT8;
+ case Types.NUMERIC:
case Types.DECIMAL:
- return PG_TYPE_NUMERIC;
+ return PG_TYPE_NUMERIC;
+ case Types.FLOAT:
case Types.REAL:
- return PG_TYPE_FLOAT4;
+ return PG_TYPE_FLOAT4;
case Types.DOUBLE:
return PG_TYPE_FLOAT8;
case Types.TIME:
@@ -571,14 +674,44 @@
return PG_TYPE_DATE;
case Types.TIMESTAMP:
return PG_TYPE_TIMESTAMP_NO_TMZONE;
- case Types.VARBINARY:
- return PG_TYPE_BYTEA;
- case Types.BLOB:
- return PG_TYPE_OID;
- case Types.ARRAY:
- return PG_TYPE_TEXTARRAY;
+
+ case Types.BLOB:
+ case Types.BINARY:
+ case Types.VARBINARY:
+ case Types.LONGVARBINARY:
+ return PG_TYPE_BYTEA;
+
+ case Types.LONGVARCHAR:
+ case Types.CLOB:
+ return PG_TYPE_TEXT;
+
+ case Types.SQLXML:
+ return PG_TYPE_TEXT;
+
default:
return PG_TYPE_UNKNOWN;
}
}
+
+ private static final byte[] hexChars = {'0', '1', '2', '3', '4', '5', '6', '7', '8', '9', 'a', 'b', 'c', 'd', 'e','f' };
+
+ /**
+ * When sending the byteA content to client convert into Hex before sending the content.
+ * @param b
+ * @return
+ * @throws IOException
+ */
+ static byte[] toHex(byte[] b) throws IOException {
+ byte[] hexbytes = PgFrontendProtocol.createByteArray((2 * b.length)+2);
+ hexbytes[0] = '\\';
+ hexbytes[1] = 'x';
+
+ for (int i = 0; i < b.length; i++) {
+ int index = (i*2)+2;
+ int v = b[i] & 0xff;
+ hexbytes[index] = hexChars[v >> 4];
+ hexbytes[index+1] = hexChars[v & 0xf];
+ }
+ return hexbytes;
+ }
}
Modified: trunk/runtime/src/main/java/org/teiid/transport/PgFrontendProtocol.java
===================================================================
--- trunk/runtime/src/main/java/org/teiid/transport/PgFrontendProtocol.java 2011-02-10 19:56:37 UTC (rev 2903)
+++ trunk/runtime/src/main/java/org/teiid/transport/PgFrontendProtocol.java 2011-02-14 01:30:06 UTC (rev 2904)
@@ -47,6 +47,15 @@
@SuppressWarnings("nls")
public class PgFrontendProtocol extends FrameDecoder {
+ private static final int LO_CREAT = 957;
+ private static final int LO_OPEN = 952;
+ private static final int LO_CLOSE = 953;
+ private static final int LO_READ = 954;
+ private static final int LO_WRITE = 955;
+ private static final int LO_LSEEK = 956;
+ private static final int LO_TELL = 958;
+ private static final int LO_UNLINK = 964;
+
private int maxObjectSize;
private Byte messageType;
private Integer dataLength;
@@ -148,7 +157,9 @@
case 'C':
return buildClose(data);
case 'H':
- return buildFlush();
+ return buildFlush();
+ case 'F':
+ return buildFunctionCall(data);
default:
return buildError();
}
@@ -179,6 +190,13 @@
int version = data.readInt();
props.setProperty("version", Integer.toString(version));
+ // SSL Request
+ if (version == 80877103) {
+ this.initialized = false;
+ this.odbcProxy.sslRequest();
+ return message;
+ }
+
trace("StartupMessage");
trace(" version " + version + " (" + (version >> 16) + "." + (version & 0xff) + ")");
@@ -235,7 +253,7 @@
}
int paramCount = data.readShort();
- Object[] params = new String[paramCount];
+ Object[] params = new Object[paramCount];
for (int i = 0; i < paramCount; i++) {
int paramLen = data.readInt();
byte[] paramdata = createByteArray(paramLen);
@@ -299,7 +317,7 @@
return message;
}
- private byte[] createByteArray(int length) throws StreamCorruptedException{
+ static byte[] createByteArray(int length) throws StreamCorruptedException{
try {
return new byte[length];
} catch(OutOfMemoryError e) {
@@ -322,6 +340,66 @@
return message;
}
+ /**
+ * LO functions are always binary, so I am ignoring the formats, return types. The below is not used
+ * leaving for future if ever LO is revisited
+ */
+ @SuppressWarnings("unused")
+ private Object buildFunctionCall(NullTerminatedStringDataInputStream data) throws IOException {
+ int funcID = data.readInt();
+
+ // read data types of arguments
+ int formatCount = data.readShort();
+ int[] formatTypes = new int[formatCount];
+ for (int i = 0; i< formatCount; i++) {
+ formatTypes[i] = data.readShort();
+ }
+
+ // arguments
+ data.readShort(); // ignore the param count; we know them by functions supported.
+ int oid = readInt(data);
+ switch(funcID) {
+ case LO_CREAT:
+ break;
+ case LO_OPEN:
+ int mode = readInt(data);
+ break;
+ case LO_CLOSE:
+ break;
+ case LO_READ:
+ int length = readInt(data);
+ break;
+ case LO_WRITE:
+ byte[] contents = readByteArray(data);
+ break;
+ case LO_LSEEK:
+ int offset = readInt(data);
+ int where = readInt(data);
+ break;
+ case LO_TELL:
+ break;
+ case LO_UNLINK:
+ break;
+ }
+ this.odbcProxy.functionCall(oid);
+ return message;
+ }
+
+ private int readInt(NullTerminatedStringDataInputStream data) throws IOException {
+ data.readInt(); // ignore this this is length always 4
+ return data.readInt();
+ }
+
+ private byte[] readByteArray(NullTerminatedStringDataInputStream data) throws IOException {
+ int length = data.readInt();
+ if (length == -1 || length == 0) {
+ return null;
+ }
+ byte[] content = createByteArray(length);
+ data.read(content, 0, length);
+ return content;
+ }
+
static class NullTerminatedStringDataInputStream extends DataInputStream{
private String encoding;
Modified: trunk/runtime/src/main/resources/org/teiid/runtime/i18n.properties
===================================================================
--- trunk/runtime/src/main/resources/org/teiid/runtime/i18n.properties 2011-02-10 19:56:37 UTC (rev 2903)
+++ trunk/runtime/src/main/resources/org/teiid/runtime/i18n.properties 2011-02-14 01:30:06 UTC (rev 2904)
@@ -87,3 +87,4 @@
error_closing_stmt=Error closing portal statement {0}
model_metadata_loading=VDB "{0}" - "{1}" model metadata is currently being loaded. Start Time: {2}
ambigious_name=Ambiguous VDB name specified. Only single occurrence of the "." is allowed in the VDB name. Also, when version based vdb name is specified, then a separate "version" connection option is not allowed:{0}.{1}
+lo_not_supported=LO functions are not supported
\ No newline at end of file
More information about the teiid-commits
mailing list