📄 netstatementrequest.java
字号:
} else { throw new SqlException(netAgent_.logWriter_, e, "Error obtaining length of blob object, exception follows. "); } } } else if (((Blob) b).isBinaryStream()) { writeScalarStream(chainFlag, chainedWithSameCorrelator, CodePoint.EXTDTA, (int) ((Blob) b).length(), ((Blob) b).getBinaryStream(), writeNullByte, index + 1); } else { // must be a binary string // note: a possible optimization is to use writeScalarLobBytes // when the input is small // use this: if (b.length () < DssConstants.MAX_DSS_LEN - 6 - 4) // writeScalarLobBytes (...) // Yes, this would avoid having to new up a java.io.ByteArrayInputStream writeScalarStream(chainFlag, chainedWithSameCorrelator, CodePoint.EXTDTA, (int) ((Blob) b).length(), ((Blob) b).getBinaryStream(), writeNullByte, index + 1); } } // the follow types are possible due to promotion to CLOB else if ( parameterType == Types.CLOB || parameterType == Types.CHAR || parameterType == Types.VARCHAR || parameterType == Types.LONGVARCHAR) { Clob o = (Clob) retrievePromotedParameterIfExists(index); java.sql.Clob c = (o == null) ? (java.sql.Clob) inputRow[index] : o; boolean isExternalClob = !(c instanceof org.apache.derby.client.am.Clob); if (isExternalClob) { try { writeScalarStream(chainFlag, chainedWithSameCorrelator, CodePoint.EXTDTA, (int) c.length(), c.getCharacterStream(), writeNullByte, index + 1); } catch (java.sql.SQLException e) { if (!(e instanceof org.apache.derby.client.am.SqlException)) { SqlException toThrow = new SqlException(netAgent_.logWriter_, "Error occurred while streaming from external clob object, exception follows. "); toThrow.setNextException(e); throw toThrow; } else { throw new SqlException(netAgent_.logWriter_, e, "Error obtaining length of blob object, exception follows. "); } } } else if (((Clob) c).isCharacterStream()) { writeScalarStream(chainFlag, chainedWithSameCorrelator, CodePoint.EXTDTA, (int) ((Clob) c).length(), ((Clob) c).getCharacterStream(), writeNullByte, index + 1); } else if (((Clob) c).isAsciiStream()) { writeScalarStream(chainFlag, chainedWithSameCorrelator, CodePoint.EXTDTA, (int) ((Clob) c).length(), ((Clob) c).getAsciiStream(), writeNullByte, index + 1); } else if (((Clob) c).isUnicodeStream()) { writeScalarStream(chainFlag, chainedWithSameCorrelator, CodePoint.EXTDTA, (int) ((Clob) c).length(), ((Clob) c).getUnicodeStream(), writeNullByte, index + 1); } else { // must be a String // note: a possible optimization is to use writeScalarLobBytes // when the input is small. // use this: if (c.length () < DssConstants.MAX_DSS_LEN - 6 - 4) // writeScalarLobBytes (...) writeScalarStream(chainFlag, chainedWithSameCorrelator, CodePoint.EXTDTA, (int) ((Clob) c).getUTF8Length(), new java.io.ByteArrayInputStream(((Clob) c).getUtf8String()), writeNullByte, index + 1); } } } } } //-------------------------helper methods------------------------------------- // returns the a promototedParameter object for index or null if it does not exist private Object retrievePromotedParameterIfExists(int index) { // consider using a nonsynchronized container or array if (promototedParameters_.isEmpty()) { return null; } return promototedParameters_.get(new Integer(index)); } private int calculateColumnsInSQLDTAGRPtriplet(int numVars) { if (numVars > FdocaConstants.MAX_VARS_IN_NGDA) //rename to MAX_VARS_IN_SQLDTAGRP_TRIPLET { return FdocaConstants.MAX_VARS_IN_NGDA; } return numVars; } // Consider refacctor so that this does not even have to look // at the actual object data, and only uses tags from the meta data // only have to call this once, rather than calling this for every input row // backburner: after refactoring this, later on, think about replacing case statements with table lookups private java.util.Hashtable computeProtocolTypesAndLengths(Object[] inputRow, ColumnMetaData parameterMetaData, int[][] lidAndLengths, java.util.Hashtable overrideMap) throws SqlException { int numVars = parameterMetaData.columns_; String s = null; if (!promototedParameters_.isEmpty()) { promototedParameters_.clear(); } for (int i = 0; i < numVars; i++) { int jdbcType; // Send the input type unless it is not available. // (e.g an output parameter) jdbcType = parameterMetaData.clientParamtertype_[i]; if (jdbcType == 0) { jdbcType = parameterMetaData.types_[i]; } // jdbc semantics - This should happen outside of the build methods // if describe input is not supported, we require the user to at least // call setNull() and provide the type information. Otherwise, we won't // be able to guess the right PROTOCOL type to send to the server, and an // exception is thrown. if (jdbcType == 0) { throw new SqlException(netAgent_.logWriter_, "Invalid JDBC Type for parameter " + i); } switch (jdbcType) { case java.sql.Types.CHAR: case java.sql.Types.VARCHAR: // lid: PROTOCOL_TYPE_NVARMIX, length override: 32767 (max) // dataFormat: String // this won't work if 1208 is not supported s = (String) inputRow[i]; // assumes UTF-8 characters at most 3 bytes long // Flow the String as a VARCHAR if (s == null || s.length() <= 32767 / 3) { lidAndLengths[i][0] = FdocaConstants.PROTOCOL_TYPE_NVARMIX; lidAndLengths[i][1] = 32767; } else { // Flow the data as CLOB data if the data too large to for LONGVARCHAR java.io.ByteArrayInputStream bais = null; byte[] ba = null; try { ba = s.getBytes("UTF-8"); bais = new java.io.ByteArrayInputStream(ba); Clob c = new Clob(netAgent_, bais, "UTF-8", ba.length); // inputRow[i] = c; // Place the new Lob in the promototedParameter_ collection for // NetStatementRequest use promototedParameters_.put(new Integer(i), c); lidAndLengths[i][0] = FdocaConstants.PROTOCOL_TYPE_NLOBCMIXED; lidAndLengths[i][1] = buildPlaceholderLength(c.length()); } catch (java.io.UnsupportedEncodingException e) { throw new SqlException(netAgent_.logWriter_, e, "Error in building String parameter: throwable attached"); } } break; case java.sql.Types.INTEGER: // lid: PROTOCOL_TYPE_NINTEGER, length override: 4 // dataFormat: Integer lidAndLengths[i][0] = FdocaConstants.PROTOCOL_TYPE_NINTEGER; lidAndLengths[i][1] = 4; break; case java.sql.Types.SMALLINT: case java.sql.Types.TINYINT: case java.sql.Types.BOOLEAN: case java.sql.Types.BIT: // lid: PROTOCOL_TYPE_NSMALL, length override: 2 // dataFormat: Short lidAndLengths[i][0] = FdocaConstants.PROTOCOL_TYPE_NSMALL; lidAndLengths[i][1] = 2; break; case java.sql.Types.REAL: // lid: PROTOCOL_TYPE_NFLOAT4, length override: 4 // dataFormat: Float lidAndLengths[i][0] = FdocaConstants.PROTOCOL_TYPE_NFLOAT4; lidAndLengths[i][1] = 4; break; case java.sql.Types.DOUBLE: case java.sql.Types.FLOAT: // lid: PROTOCOL_TYPE_NFLOAT8, length override: 8 // dataFormat: Double lidAndLengths[i][0] = FdocaConstants.PROTOCOL_TYPE_NFLOAT8; lidAndLengths[i][1] = 8; break; case java.sql.Types.NUMERIC: case java.sql.Types.DECIMAL: // lid: PROTOCOL_TYPE_NDECIMAL // dataFormat: java.math.BigDecimal // input only: // if null and describe input - use describe input precision and scale // if not null and describe input - calculate precision and actual scale from data // if null and no describe input - guess with precision 1 scale 0 // if not null and no describe input - calculate precision and actual scale from data // output only: // use largest precision/scale based on registered scale from registerOutParameter // inout: // if null - use largest precision/scale based on scale from registerOutParameter // if not null - write bigDecimal () pass registered scale so it can pad, you don't even // have to look at the actual scale at this level. /* if (parameterMetaData.isGuessed) { java.math.BigDecimal bigDecimal = (java.math.BigDecimal) inputRow[i]; int precision = Utils.computeBigDecimalPrecision (bigDecimal); lidAndLengths[i][1] = (precision << 8) + // use precision above (bigDecimal.scale() << 0); } */ // Split this entire method into two parts, the first method is called only once and the inputRow is not passed,!! // the second method is called for every inputRow and overrides inputDA lengths/scales based upon the acutal data! // for decimal and blob columns only int precision = parameterMetaData.sqlPrecision_[i]; int scale = parameterMetaData.sqlScale_[i]; lidAndLengths[i][0] = FdocaConstants.PROTOCOL_TYPE_NDECIMAL; lidAndLengths[i][1] = (precision << 8) + (scale << 0); break; case java.sql.Types.DATE: // for input, output, and inout parameters // lid: PROTOCOL_TYPE_NDATE, length override: 8 // dataFormat: java.sql.Date lidAndLengths[i][0] = FdocaConstants.PROTOCOL_TYPE_NDATE; lidAndLengths[i][1] = 10; break; case java.sql.Types.TIME: // for input, output, and inout parameters // lid: PROTOCOL_TYPE_NTIME, length override: 8 // dataFormat: java.sql.Time lidAndLengths[i][0] = FdocaConstants.PROTOCOL_TYPE_NTIME; lidAndLengths[i][1] = 8; break; case java.sql.Types.TIMESTAMP: // for input, output, and inout parameters // lid: PROTOCOL_TYPE_NTIME, length overrid: 26 // dataFormat: java.sql.Timestamp lidAndLengths[i][0] = FdocaConstants.PROTOCOL_TYPE_NTIMESTAMP; lidAndLengths[i][1] = 26; break; case java.sql.Types.BIGINT: // if SQLAM < 6 this should be mapped to decimal (19,0) in common layer // if SQLAM >=6, lid: PROTOCOL_TYPE_NINTEGER8, length override: 8 // dataFormat: Long lidAndLengths[i][0] = FdocaConstants.PROTOCOL_TYPE_NINTEGER8; lidAndLengths[i][1] = 8; break; case java.sql.Types.LONGVARCHAR: // Is this the right thing to do // should this be 32700 s = (String) inputRow[i]; if (s == null || s.length() <= 32767 / 3) { lidAndLengths[i][0] = FdocaConstants.PROTOCOL_TYPE_NLONGMIX; lidAndLengths[i][1] = 32767; } else { // Flow the data as CLOB data if the data too large to for LONGVARCHAR java.io.ByteArrayInputStream bais = null; byte[] ba = null;
⌨️ 快捷键说明
复制代码
Ctrl + C
搜索代码
Ctrl + F
全屏模式
F11
切换主题
Ctrl + Shift + D
显示快捷键
?
增大字号
Ctrl + =
减小字号
Ctrl + -