0001: /*
0002:
0003: Derby - Class org.apache.derby.client.am.CrossConverters
0004:
0005: Licensed to the Apache Software Foundation (ASF) under one or more
0006: contributor license agreements. See the NOTICE file distributed with
0007: this work for additional information regarding copyright ownership.
0008: The ASF licenses this file to You under the Apache License, Version 2.0
0009: (the "License"); you may not use this file except in compliance with
0010: the License. You may obtain a copy of the License at
0011:
0012: http://www.apache.org/licenses/LICENSE-2.0
0013:
0014: Unless required by applicable law or agreed to in writing, software
0015: distributed under the License is distributed on an "AS IS" BASIS,
0016: WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
0017: See the License for the specific language governing permissions and
0018: limitations under the License.
0019:
0020: */
0021:
0022: package org.apache.derby.client.am;
0023:
0024: import org.apache.derby.shared.common.reference.SQLState;
0025:
0026: // All currently supported derby types are mapped to one of the following jdbc types:
0027: // java.sql.Types.SMALLINT;
0028: // java.sql.Types.INTEGER;
0029: // java.sql.Types.BIGINT;
0030: // java.sql.Types.REAL;
0031: // java.sql.Types.DOUBLE;
0032: // java.sql.Types.DECIMAL;
0033: // java.sql.Types.DATE;
0034: // java.sql.Types.TIME;
0035: // java.sql.Types.TIMESTAMP;
0036: // java.sql.Types.CHAR;
0037: // java.sql.Types.VARCHAR;
0038: // java.sql.Types.LONGVARCHAR;
0039: // java.sql.Types.CLOB;
0040: // java.sql.Types.BLOB;
0041: //
0042:
0043: final class CrossConverters {
0044:
0045: /**
0046: * Value used to signal unknown length of data.
0047: */
0048: public static final int UNKNOWN_LENGTH = Integer.MIN_VALUE;
0049:
0050: private final static java.math.BigDecimal bdMaxByteValue__ = java.math.BigDecimal
0051: .valueOf(Byte.MAX_VALUE);
0052: private final static java.math.BigDecimal bdMinByteValue__ = java.math.BigDecimal
0053: .valueOf(Byte.MIN_VALUE);
0054: private final static java.math.BigDecimal bdMaxShortValue__ = java.math.BigDecimal
0055: .valueOf(Short.MAX_VALUE);
0056: private final static java.math.BigDecimal bdMinShortValue__ = java.math.BigDecimal
0057: .valueOf(Short.MIN_VALUE);
0058: private final static java.math.BigDecimal bdMaxIntValue__ = java.math.BigDecimal
0059: .valueOf(Integer.MAX_VALUE);
0060: private final static java.math.BigDecimal bdMinIntValue__ = java.math.BigDecimal
0061: .valueOf(Integer.MIN_VALUE);
0062: private final static java.math.BigDecimal bdMaxLongValue__ = java.math.BigDecimal
0063: .valueOf(Long.MAX_VALUE);
0064: private final static java.math.BigDecimal bdMinLongValue__ = java.math.BigDecimal
0065: .valueOf(Long.MIN_VALUE);
0066: private final static java.math.BigDecimal bdMaxFloatValue__ = new java.math.BigDecimal(
0067: Float.MAX_VALUE);
0068: private final static java.math.BigDecimal bdMinFloatValue__ = new java.math.BigDecimal(
0069: -Float.MAX_VALUE);
0070: private final static java.math.BigDecimal bdMaxDoubleValue__ = new java.math.BigDecimal(
0071: Double.MAX_VALUE);
0072: private final static java.math.BigDecimal bdMinDoubleValue__ = new java.math.BigDecimal(
0073: -Double.MAX_VALUE);
0074:
0075: // Since BigDecimals are immutable, we can return pointers to these canned 0's and 1's.
0076: private final static java.math.BigDecimal bdZero__ = java.math.BigDecimal
0077: .valueOf(0);
0078: private final static java.math.BigDecimal bdOne__ = java.math.BigDecimal
0079: .valueOf(1);
0080:
0081: // ---------------------- state ----------------------------------------------
0082:
0083: Agent agent_;
0084:
0085: // ----------------------constructors/finalizer-------------------------------
0086:
0087: CrossConverters(Agent agent) {
0088: agent_ = agent;
0089: }
0090:
0091: // ---------------------------------------------------------------------------
0092: // The following methods are used for input cross conversion.
0093: // ---------------------------------------------------------------------------
0094:
0095: //---------------------------- setObject() methods ---------------------------
0096:
0097: // Convert from boolean source to target type.
0098: // In support of PS.setBoolean().
0099: // See differences.html for DNC setBoolean() semantics.
0100: final Object setObject(int targetType, boolean source)
0101: throws SqlException {
0102: return setObject(targetType, (short) (source ? 1 : 0));
0103: }
0104:
0105: // Convert from byte source to target type
0106: // In support of PS.setByte()
0107: final Object setObject(int targetType, byte source)
0108: throws SqlException {
0109: return setObject(targetType, (short) source);
0110: }
0111:
0112: // Convert from short source to target type
0113: // In support of PS.setShort()
0114: final Object setObject(int targetType, short source)
0115: throws SqlException {
0116: switch (targetType) {
0117: case Types.SMALLINT:
0118: return new Short(source);
0119:
0120: case Types.INTEGER:
0121: return new Integer(source);
0122:
0123: case Types.BIGINT:
0124: return new Long(source);
0125:
0126: case Types.REAL:
0127: return new Float(source);
0128:
0129: case Types.DOUBLE:
0130: return new Double(source);
0131:
0132: case Types.DECIMAL:
0133: return java.math.BigDecimal.valueOf(source);
0134:
0135: case Types.CHAR:
0136: case Types.VARCHAR:
0137: case Types.LONGVARCHAR:
0138: return String.valueOf(source);
0139:
0140: default:
0141: throw new SqlException(agent_.logWriter_,
0142: new ClientMessageId(
0143: SQLState.LANG_DATA_TYPE_SET_MISMATCH),
0144: "byte", Types.getTypeString(targetType));
0145: }
0146: }
0147:
0148: // Convert from integer source to target type
0149: // In support of PS.setInt()
0150: final Object setObject(int targetType, int source)
0151: throws SqlException {
0152: switch (targetType) {
0153: case Types.SMALLINT:
0154: if (Configuration.rangeCheckCrossConverters
0155: && (source > Short.MAX_VALUE || source < Short.MIN_VALUE)) {
0156: throw new LossOfPrecisionConversionException(
0157: agent_.logWriter_, String.valueOf(source));
0158: }
0159: return new Short((short) source);
0160:
0161: case Types.INTEGER:
0162: return new Integer(source);
0163:
0164: case Types.BIGINT:
0165: return new Long(source);
0166:
0167: case Types.REAL:
0168: return new Float(source);
0169:
0170: case Types.DOUBLE:
0171: return new Double(source);
0172:
0173: case Types.DECIMAL:
0174: return java.math.BigDecimal.valueOf(source);
0175:
0176: case Types.CHAR:
0177: case Types.VARCHAR:
0178: case Types.LONGVARCHAR:
0179: return String.valueOf(source);
0180:
0181: default:
0182: throw new SqlException(agent_.logWriter_,
0183: new ClientMessageId(
0184: SQLState.LANG_DATA_TYPE_SET_MISMATCH),
0185: "int", Types.getTypeString(targetType));
0186: }
0187: }
0188:
0189: // This method is used in lieu of setObject(targetType, sourceObject) because we
0190: // don't support the BIT/BOOLEAN as underlying DERBY targetTypes.
0191: final boolean setBooleanFromObject(Object source, int sourceType)
0192: throws SqlException {
0193: switch (sourceType) {
0194: case Types.SMALLINT:
0195: return getBooleanFromShort(((Short) source).shortValue());
0196: case Types.INTEGER:
0197: return getBooleanFromInt(((Integer) source).intValue());
0198: case Types.BIGINT:
0199: return getBooleanFromLong(((java.math.BigInteger) source)
0200: .longValue());
0201: case Types.REAL:
0202: return getBooleanFromFloat(((Float) source).floatValue());
0203: case Types.DOUBLE:
0204: return getBooleanFromDouble(((Double) source).doubleValue());
0205: case Types.DECIMAL:
0206: return getBooleanFromLong(((java.math.BigDecimal) source)
0207: .longValue());
0208: case Types.CHAR:
0209: case Types.VARCHAR:
0210: case Types.LONGVARCHAR:
0211: return getBooleanFromString((String) source);
0212: default:
0213: throw new ColumnTypeConversionException(agent_.logWriter_,
0214: Types.getTypeString(sourceType), "boolean");
0215: }
0216: }
0217:
0218: // This method is used in lieu of setObject(targetType, sourceObject) because we
0219: // don't support the BIT/BOOLEAN as underlying DERBY targetTypes.
0220: final byte setByteFromObject(Object source, int sourceType)
0221: throws SqlException {
0222: switch (sourceType) {
0223: case Types.SMALLINT:
0224: return getByteFromShort(((Short) source).shortValue());
0225: case Types.INTEGER:
0226: return getByteFromInt(((Integer) source).intValue());
0227: case Types.BIGINT:
0228: return getByteFromLong(((java.math.BigInteger) source)
0229: .longValue());
0230: case Types.REAL:
0231: return getByteFromFloat(((Float) source).floatValue());
0232: case Types.DOUBLE:
0233: return getByteFromDouble(((Double) source).doubleValue());
0234: case Types.DECIMAL:
0235: return getByteFromLong(((java.math.BigDecimal) source)
0236: .longValue());
0237: case Types.CHAR:
0238: case Types.VARCHAR:
0239: case Types.LONGVARCHAR:
0240: return getByteFromString((String) source);
0241: default:
0242: throw new ColumnTypeConversionException(agent_.logWriter_,
0243: Types.getTypeString(sourceType), "byte");
0244: }
0245: }
0246:
0247: // Convert from long source to target type
0248: // In support of PS.setLong()
0249: final Object setObject(int targetType, long source)
0250: throws SqlException {
0251: switch (targetType) {
0252: case Types.SMALLINT:
0253: if (Configuration.rangeCheckCrossConverters
0254: && (source > Short.MAX_VALUE || source < Short.MIN_VALUE)) {
0255: throw new LossOfPrecisionConversionException(
0256: agent_.logWriter_, String.valueOf(source));
0257: }
0258: return new Short((short) source);
0259:
0260: case Types.INTEGER:
0261: if (Configuration.rangeCheckCrossConverters
0262: && (source > Integer.MAX_VALUE || source < Integer.MIN_VALUE)) {
0263: throw new LossOfPrecisionConversionException(
0264: agent_.logWriter_, String.valueOf(source));
0265: }
0266: return new Integer((int) source);
0267:
0268: case Types.BIGINT:
0269: return new Long(source);
0270:
0271: case Types.REAL:
0272: return new Float(source);
0273:
0274: case Types.DOUBLE:
0275: return new Double(source);
0276:
0277: case Types.DECIMAL:
0278: return java.math.BigDecimal.valueOf(source);
0279:
0280: case Types.CHAR:
0281: case Types.VARCHAR:
0282: case Types.LONGVARCHAR:
0283: return String.valueOf(source);
0284:
0285: default:
0286: throw new SqlException(agent_.logWriter_,
0287: new ClientMessageId(
0288: SQLState.LANG_DATA_TYPE_SET_MISMATCH),
0289: "long", Types.getTypeString(targetType));
0290: }
0291: }
0292:
0293: // Convert from floating point source to target type
0294: // In support of PS.setFloat()
0295: final Object setObject(int targetType, float source)
0296: throws SqlException {
0297: switch (targetType) {
0298: case Types.SMALLINT:
0299: if (Configuration.rangeCheckCrossConverters
0300: && (source > Short.MAX_VALUE || source < Short.MIN_VALUE)) {
0301: throw new LossOfPrecisionConversionException(
0302: agent_.logWriter_, String.valueOf(source));
0303: }
0304: return new Short((short) source);
0305:
0306: case Types.INTEGER:
0307: if (Configuration.rangeCheckCrossConverters
0308: && (source > Integer.MAX_VALUE || source < Integer.MIN_VALUE)) {
0309: throw new LossOfPrecisionConversionException(
0310: agent_.logWriter_, String.valueOf(source));
0311: }
0312: return new Integer((int) source);
0313:
0314: case Types.BIGINT:
0315: if (Configuration.rangeCheckCrossConverters
0316: && (source > Long.MAX_VALUE || source < Long.MIN_VALUE)) {
0317: throw new LossOfPrecisionConversionException(
0318: agent_.logWriter_, String.valueOf(source));
0319: }
0320: return new Long((long) source);
0321:
0322: case Types.REAL:
0323: if (Configuration.rangeCheckCrossConverters &&
0324: // change the check from (source > Float.MAX_VALUE || source < -Float.MIN_VALUE))
0325: // to the following:
0326: //-----------------------------------------------------------------------------------
0327: // -infinity 0 +infinity
0328: // |__________________________|======|________________________|
0329: // <-3.4E+38| | | |>+3.4E+38
0330: // | | |_________________ |
0331: // | |-1.4E-45 <X< +1.4E-45
0332: // | |________________________
0333: //-----------------------------------------------------------------------------------
0334: (source == Float.POSITIVE_INFINITY || source == Float.NEGATIVE_INFINITY)) {
0335: throw new LossOfPrecisionConversionException(
0336: agent_.logWriter_, String.valueOf(source));
0337: }
0338: return new Float(source);
0339:
0340: case Types.DOUBLE:
0341: if (Configuration.rangeCheckCrossConverters &&
0342: //-------------------------------------------------------------------------------------
0343: // -infinity 0 +infinity
0344: // |__________________________|======|________________________|
0345: // <-1.79E+308| | | |>+1.79E+308
0346: // | | |_________________ |
0347: // | |-4.9E-324 <X< +4.9E-324
0348: // | |________________________
0349: //-------------------------------------------------------------------------------------
0350: (source == Double.POSITIVE_INFINITY || source == Double.NEGATIVE_INFINITY)) {
0351: throw new LossOfPrecisionConversionException(
0352: agent_.logWriter_, String.valueOf(source));
0353: }
0354: // source passed in is a float, do we need to check if the source already contains "infinity"??
0355: return new Double(String.valueOf(source));
0356:
0357: case Types.DECIMAL:
0358: // Can't use the following commented out line because it changes precision of the result.
0359: //return new java.math.BigDecimal (source);
0360: return new java.math.BigDecimal(String.valueOf(source)); // This matches derby semantics
0361:
0362: case Types.CHAR:
0363: case Types.VARCHAR:
0364: case Types.LONGVARCHAR:
0365: return String.valueOf(source);
0366:
0367: default:
0368: throw new SqlException(agent_.logWriter_,
0369: new ClientMessageId(
0370: SQLState.LANG_DATA_TYPE_SET_MISMATCH),
0371: "float", Types.getTypeString(targetType));
0372: }
0373: }
0374:
0375: // Convert from double floating point source to target type
0376: // In support of PS.setDouble()
0377: final Object setObject(int targetType, double source)
0378: throws SqlException {
0379: switch (targetType) {
0380: case Types.SMALLINT:
0381: if (Configuration.rangeCheckCrossConverters
0382: && (source > Short.MAX_VALUE || source < Short.MIN_VALUE)) {
0383: throw new LossOfPrecisionConversionException(
0384: agent_.logWriter_, String.valueOf(source));
0385: }
0386: return new Short((short) source);
0387:
0388: case Types.INTEGER:
0389: if (Configuration.rangeCheckCrossConverters
0390: && (source > Integer.MAX_VALUE || source < Integer.MIN_VALUE)) {
0391: throw new LossOfPrecisionConversionException(
0392: agent_.logWriter_, String.valueOf(source));
0393: }
0394: return new Integer((int) source);
0395:
0396: case Types.BIGINT:
0397: if (Configuration.rangeCheckCrossConverters
0398: && (source > Long.MAX_VALUE || source < Long.MIN_VALUE)) {
0399: throw new LossOfPrecisionConversionException(
0400: agent_.logWriter_, String.valueOf(source));
0401: }
0402: return new Long((long) source);
0403:
0404: case Types.REAL:
0405: if (Configuration.rangeCheckCrossConverters
0406: && (source > Float.MAX_VALUE || source < -Float.MAX_VALUE)) {
0407: throw new LossOfPrecisionConversionException(
0408: agent_.logWriter_, String.valueOf(source));
0409: }
0410: return new Float((float) source);
0411:
0412: case Types.DOUBLE:
0413: if (Configuration.rangeCheckCrossConverters &&
0414: // change the check from (source > Double.MAX_VALUE || source < -Double.MIN_VALUE))
0415: // to the following:
0416: //-------------------------------------------------------------------------------------
0417: // -infinity 0 +infinity
0418: // |__________________________|======|________________________|
0419: // <-1.79E+308| | | |>+1.79E+308
0420: // | | |_________________ |
0421: // | |-4.9E-324 <X< +4.9E-324
0422: // | |________________________
0423: //-------------------------------------------------------------------------------------
0424: (source == Double.POSITIVE_INFINITY || source == Double.NEGATIVE_INFINITY)) {
0425: throw new LossOfPrecisionConversionException(
0426: agent_.logWriter_, String.valueOf(source));
0427: }
0428: return new Double(source);
0429:
0430: case Types.DECIMAL:
0431: return new java.math.BigDecimal(String.valueOf(source)); // This matches derby semantics
0432: case Types.CHAR:
0433: case Types.VARCHAR:
0434: case Types.LONGVARCHAR:
0435: return String.valueOf(source);
0436:
0437: default:
0438: throw new SqlException(agent_.logWriter_,
0439: new ClientMessageId(
0440: SQLState.LANG_DATA_TYPE_SET_MISMATCH),
0441: "double", Types.getTypeString(targetType));
0442: }
0443: }
0444:
0445: // Convert from big decimal source to target type
0446: // In support of PS.setBigDecimal()
0447: final Object setObject(int targetType, java.math.BigDecimal source)
0448: throws SqlException {
0449: switch (targetType) {
0450: case Types.SMALLINT:
0451: if (Configuration.rangeCheckCrossConverters
0452: && (source.compareTo(bdMaxShortValue__) == 1 || source
0453: .compareTo(bdMinShortValue__) == -1)) {
0454: throw new LossOfPrecisionConversionException(
0455: agent_.logWriter_, String.valueOf(source));
0456: }
0457: return new Short(source.shortValue());
0458:
0459: case Types.INTEGER:
0460: if (Configuration.rangeCheckCrossConverters
0461: && (source.compareTo(bdMaxIntValue__) == 1 || source
0462: .compareTo(bdMinIntValue__) == -1)) {
0463: throw new LossOfPrecisionConversionException(
0464: agent_.logWriter_, String.valueOf(source));
0465: }
0466: return new Integer(source.intValue());
0467:
0468: case Types.BIGINT:
0469: if (Configuration.rangeCheckCrossConverters
0470: && (source.compareTo(bdMaxLongValue__) == 1 || source
0471: .compareTo(bdMinLongValue__) == -1)) {
0472: throw new LossOfPrecisionConversionException(
0473: agent_.logWriter_, String.valueOf(source));
0474: }
0475: return new Long(source.longValue());
0476:
0477: case Types.REAL:
0478: if (Configuration.rangeCheckCrossConverters
0479: && (source.compareTo(bdMaxFloatValue__) == 1 || source
0480: .compareTo(bdMinFloatValue__) == -1)) {
0481: throw new LossOfPrecisionConversionException(
0482: agent_.logWriter_, String.valueOf(source));
0483: }
0484: return new Float(source.floatValue());
0485:
0486: case Types.DOUBLE:
0487: if (Configuration.rangeCheckCrossConverters
0488: && (source.compareTo(bdMaxDoubleValue__) == 1 || source
0489: .compareTo(bdMinDoubleValue__) == -1)) {
0490: throw new LossOfPrecisionConversionException(
0491: agent_.logWriter_, String.valueOf(source));
0492: }
0493: return new Double(source.doubleValue());
0494:
0495: case Types.DECIMAL:
0496: return source;
0497:
0498: case Types.CHAR:
0499: case Types.VARCHAR:
0500: case Types.LONGVARCHAR:
0501: return String.valueOf(source);
0502:
0503: default:
0504: throw new SqlException(agent_.logWriter_,
0505: new ClientMessageId(
0506: SQLState.LANG_DATA_TYPE_SET_MISMATCH),
0507: "java.Math.BigDecimal", Types
0508: .getTypeString(targetType));
0509: }
0510: }
0511:
0512: // Convert from date source to target type
0513: // In support of PS.setDate()
0514: final Object setObject(int targetType, java.sql.Date source)
0515: throws SqlException {
0516: switch (targetType) {
0517:
0518: case java.sql.Types.DATE:
0519: return source;
0520:
0521: case java.sql.Types.TIMESTAMP:
0522: return new java.sql.Timestamp(source.getTime());
0523:
0524: case java.sql.Types.CHAR:
0525: case java.sql.Types.VARCHAR:
0526: case java.sql.Types.LONGVARCHAR:
0527: return String.valueOf(source);
0528:
0529: default:
0530: throw new SqlException(agent_.logWriter_,
0531: new ClientMessageId(
0532: SQLState.LANG_DATA_TYPE_SET_MISMATCH),
0533: "java.sql.Date", Types.getTypeString(targetType));
0534: }
0535: }
0536:
0537: // Convert from time source to target type
0538: // In support of PS.setTime()
0539: final Object setObject(int targetType, java.sql.Time source)
0540: throws SqlException {
0541: switch (targetType) {
0542:
0543: case java.sql.Types.TIME:
0544: return source;
0545:
0546: case java.sql.Types.CHAR:
0547: case java.sql.Types.VARCHAR:
0548: case java.sql.Types.LONGVARCHAR:
0549: return String.valueOf(source);
0550:
0551: default:
0552: throw new SqlException(agent_.logWriter_,
0553: new ClientMessageId(
0554: SQLState.LANG_DATA_TYPE_SET_MISMATCH),
0555: "java.sql.Time", Types.getTypeString(targetType));
0556: }
0557: }
0558:
0559: // Convert from date source to target type
0560: // In support of PS.setTimestamp()
0561: final Object setObject(int targetType, java.sql.Timestamp source)
0562: throws SqlException {
0563: switch (targetType) {
0564:
0565: case java.sql.Types.TIMESTAMP:
0566: return source;
0567:
0568: case java.sql.Types.TIME:
0569: return new java.sql.Time(source.getTime());
0570:
0571: case java.sql.Types.DATE:
0572: return new java.sql.Date(source.getTime());
0573:
0574: case java.sql.Types.CHAR:
0575: case java.sql.Types.VARCHAR:
0576: case java.sql.Types.LONGVARCHAR:
0577: return String.valueOf(source);
0578:
0579: default:
0580: throw new SqlException(agent_.logWriter_,
0581: new ClientMessageId(
0582: SQLState.LANG_DATA_TYPE_SET_MISMATCH),
0583: "java.sql.Timestamp", Types
0584: .getTypeString(targetType));
0585: }
0586: }
0587:
0588: // setString() against BINARY columns cannot be implemented consistently because w/out metadata, we'll send char encoding bytes.
0589: // So we refuse setString() requests altogether.
0590: // Convert from string source to target type.
0591: // In support of PS.setString()
0592: final Object setObject(int targetDriverType, String source)
0593: throws SqlException {
0594: try {
0595: switch (targetDriverType) {
0596: case Types.SMALLINT:
0597: return Short.valueOf(source);
0598:
0599: case Types.INTEGER:
0600: return Integer.valueOf(source);
0601:
0602: case Types.BIGINT:
0603: return Long.valueOf(source);
0604:
0605: case Types.REAL:
0606: return Float.valueOf(source);
0607:
0608: case Types.DOUBLE:
0609: return Double.valueOf(source);
0610:
0611: case Types.DECIMAL:
0612: return new java.math.BigDecimal(source);
0613:
0614: case java.sql.Types.DATE:
0615: return date_valueOf(source);
0616:
0617: case java.sql.Types.TIME:
0618: return time_valueOf(source);
0619:
0620: case java.sql.Types.TIMESTAMP:
0621: return timestamp_valueOf(source);
0622:
0623: case Types.CHAR:
0624: case Types.VARCHAR:
0625: case Types.LONGVARCHAR:
0626: return source;
0627:
0628: case Types.CLOB:
0629: return new Clob(agent_, source);
0630:
0631: // setString() against BINARY columns is problematic because w/out metadata, we'll send char encoding bytes.
0632: // So we refuse setString() requests altogether.
0633: case Types.BINARY:
0634: case Types.VARBINARY:
0635: case Types.LONGVARBINARY:
0636: case Types.BLOB:
0637: default:
0638: throw new SqlException(agent_.logWriter_,
0639: new ClientMessageId(
0640: SQLState.LANG_DATA_TYPE_SET_MISMATCH),
0641: "String", Types.getTypeString(targetDriverType));
0642: }
0643: } catch (java.lang.NumberFormatException e) {
0644: throw new SqlException(
0645: agent_.logWriter_,
0646: new ClientMessageId(SQLState.LANG_FORMAT_EXCEPTION),
0647: Types.getTypeString(targetDriverType), e);
0648: }
0649: }
0650:
0651: // ------ method to convert to targetJdbcType ------
0652: /**
0653: * Convert the input targetJdbcType to the correct JdbcType used by CrossConverters.
0654: */
0655: public static int getInputJdbcType(int jdbcType) {
0656: switch (jdbcType) {
0657: case java.sql.Types.BIT:
0658: case java.sql.Types.BOOLEAN:
0659: case java.sql.Types.TINYINT:
0660: case java.sql.Types.SMALLINT:
0661: return java.sql.Types.INTEGER;
0662: case java.sql.Types.NUMERIC:
0663: return java.sql.Types.DECIMAL;
0664: case java.sql.Types.FLOAT:
0665: return java.sql.Types.DOUBLE;
0666: default:
0667: return jdbcType;
0668: }
0669:
0670: }
0671:
0672: // -- methods in support of setObject(String)/getString() on BINARY columns---
0673:
0674: // Convert from byte[] source to target type
0675: // In support of PS.setBytes()
0676: final Object setObject(int targetType, byte[] source)
0677: throws SqlException {
0678: switch (targetType) {
0679: case Types.BINARY:
0680: case Types.VARBINARY:
0681: case Types.LONGVARBINARY:
0682: return source;
0683: case Types.BLOB:
0684: return new Blob(source, agent_, 0);
0685: default:
0686: throw new SqlException(agent_.logWriter_,
0687: new ClientMessageId(
0688: SQLState.LANG_DATA_TYPE_SET_MISMATCH),
0689: "byte[]", Types.getTypeString(targetType));
0690: }
0691: }
0692:
0693: // Convert from Reader source to target type
0694: // In support of PS.setCharacterStream()
0695: final Object setObject(int targetType, java.io.Reader source,
0696: int length) throws SqlException {
0697: switch (targetType) {
0698: case Types.CHAR:
0699: case Types.VARCHAR:
0700: case Types.LONGVARCHAR:
0701: return setStringFromReader(source, length);
0702: case Types.CLOB:
0703: if (length == CrossConverters.UNKNOWN_LENGTH) {
0704: return new Clob(agent_, source);
0705: }
0706: return new Clob(agent_, source, length);
0707: // setCharacterStream() against BINARY columns is problematic because w/out metadata, we'll send char encoding bytes.
0708: // There's no clean solution except to just not support setObject(String/Reader/Stream)
0709: case Types.BINARY:
0710: case Types.VARBINARY:
0711: case Types.LONGVARBINARY:
0712: case Types.BLOB:
0713: default:
0714: throw new SqlException(agent_.logWriter_,
0715: new ClientMessageId(
0716: SQLState.LANG_DATA_TYPE_SET_MISMATCH),
0717: "java.io.Reader", Types.getTypeString(targetType));
0718: }
0719: }
0720:
0721: // create a String by reading all of the bytes from reader
0722: private final String setStringFromReader(java.io.Reader r,
0723: int length) throws SqlException {
0724: java.io.StringWriter sw = new java.io.StringWriter();
0725: try {
0726: int read = r.read();
0727: int totalRead = 0;
0728: while (read != -1) {
0729: totalRead++;
0730: sw.write(read);
0731: read = r.read();
0732: }
0733: if (length != CrossConverters.UNKNOWN_LENGTH
0734: && length != totalRead) {
0735: throw new SqlException(agent_.logWriter_,
0736: new ClientMessageId(SQLState.READER_UNDER_RUN));
0737: }
0738: return sw.toString();
0739: } catch (java.io.IOException e) {
0740: throw SqlException.javaException(agent_.logWriter_, e);
0741: }
0742: }
0743:
0744: // Convert from InputStream source to target type.
0745: // In support of PS.setAsciiStream, PS.setUnicodeStream
0746: // Note: PS.setCharacterStream() is handled by setObject(Reader)
0747: final Object setObjectFromCharacterStream(int targetType,
0748: java.io.InputStream source, String encoding, int length)
0749: throws SqlException {
0750: switch (targetType) {
0751: case Types.CHAR:
0752: case Types.VARCHAR:
0753: case Types.LONGVARCHAR:
0754: return setStringFromStream(source, encoding, length);
0755: case Types.CLOB:
0756: if (length == CrossConverters.UNKNOWN_LENGTH) {
0757: return new Clob(agent_, source, encoding);
0758: }
0759: return new Clob(agent_, source, encoding, length);
0760: case Types.BINARY:
0761: case Types.VARBINARY:
0762: case Types.LONGVARBINARY:
0763: case Types.BLOB:
0764: default:
0765: throw new SqlException(agent_.logWriter_,
0766: new ClientMessageId(
0767: SQLState.LANG_DATA_TYPE_SET_MISMATCH),
0768: "java.io.InputStream", Types
0769: .getTypeString(targetType));
0770: }
0771: }
0772:
0773: // create a String by reading all of the bytes from inputStream, applying encoding
0774: private final String setStringFromStream(java.io.InputStream is,
0775: String encoding, int length) throws SqlException {
0776: try {
0777: java.io.ByteArrayOutputStream baos = new java.io.ByteArrayOutputStream();
0778: int totalRead = 0;
0779:
0780: try {
0781: int read = is.read();
0782: while (read != -1) {
0783: totalRead++;
0784: baos.write(read);
0785: read = is.read();
0786: }
0787: } catch (java.io.IOException e) {
0788: throw new SqlException(agent_.logWriter_,
0789: new ClientMessageId(SQLState.JAVA_EXCEPTION), e
0790: .getClass().getName(), e.getMessage(),
0791: e);
0792: }
0793:
0794: if (length != CrossConverters.UNKNOWN_LENGTH
0795: && length != totalRead) {
0796: throw new SqlException(agent_.logWriter_,
0797: new ClientMessageId(SQLState.READER_UNDER_RUN));
0798: }
0799:
0800: return new String(baos.toByteArray(), encoding);
0801: } catch (java.io.UnsupportedEncodingException e) {
0802: throw new SqlException(agent_.logWriter_,
0803: new ClientMessageId(SQLState.UNSUPPORTED_ENCODING),
0804: "java.io.InputStream", "String", e);
0805: }
0806: }
0807:
0808: // Convert from Blob source to target type
0809: // In support of PS.setBlob()
0810: final Object setObject(int targetType, java.sql.Blob source)
0811: throws SqlException {
0812: switch (targetType) {
0813: case Types.BLOB:
0814: return source;
0815: case Types.BINARY:
0816: case Types.VARBINARY:
0817: case Types.LONGVARBINARY:
0818: try {
0819: return source.getBytes(1L, (int) source.length());
0820: } catch (java.sql.SQLException e) {
0821: throw new SqlException(e);
0822: }
0823: default:
0824: throw new SqlException(agent_.logWriter_,
0825: new ClientMessageId(
0826: SQLState.LANG_DATA_TYPE_SET_MISMATCH),
0827: "java.sql.Blob", Types.getTypeString(targetType));
0828: }
0829: }
0830:
0831: // Convert from InputStream source to target type
0832: // In support of PS.setBinaryStream()
0833: final Object setObjectFromBinaryStream(int targetType,
0834: java.io.InputStream source, int length) throws SqlException {
0835: switch (targetType) {
0836: case Types.BINARY:
0837: case Types.VARBINARY:
0838: case Types.LONGVARBINARY:
0839: return setBytesFromStream(source, length);
0840: case Types.BLOB:
0841: if (length == CrossConverters.UNKNOWN_LENGTH) {
0842: return new Blob(agent_, source);
0843: }
0844: return new Blob(agent_, source, length);
0845: default:
0846: throw new SqlException(agent_.logWriter_,
0847: new ClientMessageId(
0848: SQLState.LANG_DATA_TYPE_SET_MISMATCH),
0849: "java.io.InputStream", Types
0850: .getTypeString(targetType));
0851: }
0852: }
0853:
0854: // create a byte[] by reading all of the bytes from inputStream
0855: private final byte[] setBytesFromStream(java.io.InputStream is,
0856: int length) throws SqlException {
0857: java.io.ByteArrayOutputStream baos = new java.io.ByteArrayOutputStream();
0858: int totalRead = 0;
0859:
0860: try {
0861: int read = is.read();
0862: while (read != -1) {
0863: totalRead++;
0864: baos.write(read);
0865: read = is.read();
0866: }
0867:
0868: if (length != CrossConverters.UNKNOWN_LENGTH
0869: && length != totalRead) {
0870: throw new SqlException(agent_.logWriter_,
0871: new ClientMessageId(SQLState.READER_UNDER_RUN));
0872: }
0873: } catch (java.io.IOException e) {
0874: throw SqlException.javaException(agent_.logWriter_, e);
0875: }
0876: return baos.toByteArray();
0877: }
0878:
0879: // Convert from Clob source to target type
0880: // In support of PS.setClob()
0881: final Object setObject(int targetType, java.sql.Clob source)
0882: throws SqlException {
0883: switch (targetType) {
0884: case Types.CLOB:
0885: return source;
0886: case Types.CHAR:
0887: case Types.VARCHAR:
0888: case Types.LONGVARCHAR:
0889: return source.toString();
0890: default:
0891: throw new SqlException(agent_.logWriter_,
0892: new ClientMessageId(
0893: SQLState.LANG_DATA_TYPE_SET_MISMATCH),
0894: "java.sql.Clob", Types.getTypeString(targetType));
0895: }
0896: }
0897:
0898: // The Java compiler uses static binding, so we can't rely on the strongly
0899: // typed setObject() methods above for each of the Java Object instance types.
0900: final Object setObject(int targetType, Object source)
0901: throws SqlException {
0902: if (source == null) {
0903: return null;
0904: } else if (source instanceof Boolean) {
0905: return setObject(targetType, ((Boolean) source)
0906: .booleanValue());
0907: } else if (source instanceof Integer) {
0908: return setObject(targetType, ((Integer) source).intValue());
0909: } else if (source instanceof Long) {
0910: return setObject(targetType, ((Long) source).longValue());
0911: } else if (source instanceof Float) {
0912: return setObject(targetType, ((Float) source).floatValue());
0913: } else if (source instanceof Double) {
0914: return setObject(targetType, ((Double) source)
0915: .doubleValue());
0916: } else if (source instanceof java.math.BigDecimal) {
0917: return setObject(targetType, (java.math.BigDecimal) source);
0918: } else if (source instanceof java.sql.Date) {
0919: return setObject(targetType, (java.sql.Date) source);
0920: } else if (source instanceof java.sql.Time) {
0921: return setObject(targetType, (java.sql.Time) source);
0922: } else if (source instanceof java.sql.Timestamp) {
0923: return setObject(targetType, (java.sql.Timestamp) source);
0924: } else if (source instanceof String) {
0925: return setObject(targetType, (String) source);
0926: } else if (source instanceof byte[]) {
0927: return setObject(targetType, (byte[]) source);
0928: } else if (source instanceof java.sql.Blob) {
0929: return setObject(targetType, (java.sql.Blob) source);
0930: } else if (source instanceof java.sql.Clob) {
0931: return setObject(targetType, (java.sql.Clob) source);
0932: } else if (source instanceof java.sql.Array) {
0933: return setObject(targetType, (java.sql.Array) source);
0934: } else if (source instanceof java.sql.Ref) {
0935: return setObject(targetType, (java.sql.Ref) source);
0936: } else if (source instanceof Short) {
0937: return setObject(targetType, ((Short) source).shortValue());
0938: } else if (source instanceof Byte) {
0939: return setObject(targetType, ((Byte) source).byteValue());
0940: } else {
0941: throw new SqlException(agent_.logWriter_,
0942: new ClientMessageId(
0943: SQLState.LANG_DATA_TYPE_SET_MISMATCH),
0944: source.getClass().getName(), Types
0945: .getTypeString(targetType));
0946: }
0947: }
0948:
0949: // move all these to Cursor and rename to crossConvertFrom*To*()
0950: // ---------------------------------------------------------------------------
0951: // The following methods are used for output cross conversion.
0952: // ---------------------------------------------------------------------------
0953:
0954: //---------------------------- getBoolean*() methods -------------------------
0955:
0956: final boolean getBooleanFromByte(byte source) throws SqlException {
0957: return source != 0;
0958: }
0959:
0960: final boolean getBooleanFromShort(short source) throws SqlException {
0961: return source != 0;
0962: }
0963:
0964: final boolean getBooleanFromInt(int source) throws SqlException {
0965: return source != 0;
0966: }
0967:
0968: final boolean getBooleanFromLong(long source) throws SqlException {
0969: return source != 0;
0970: }
0971:
0972: final boolean getBooleanFromFloat(float source) throws SqlException {
0973: return source != 0;
0974: }
0975:
0976: final boolean getBooleanFromDouble(double source)
0977: throws SqlException {
0978: return source != 0;
0979: }
0980:
0981: final boolean getBooleanFromBigDecimal(java.math.BigDecimal source)
0982: throws SqlException {
0983: return source.intValue() != 0;
0984: }
0985:
0986: // See differences.html for DNC getBoolean() semantics.
0987: final boolean getBooleanFromString(String source)
0988: throws SqlException {
0989: return !(source.trim().equals("0") || source.trim().equals(
0990: "false"));
0991: }
0992:
0993: //---------------------------- getByte*() methods ----------------------------
0994:
0995: final byte getByteFromShort(short source) throws SqlException {
0996: if (Configuration.rangeCheckCrossConverters
0997: && (source > java.lang.Byte.MAX_VALUE || source < java.lang.Byte.MIN_VALUE)) {
0998: throw new LossOfPrecisionConversionException(
0999: agent_.logWriter_, String.valueOf(source));
1000: }
1001:
1002: return (byte) source;
1003: }
1004:
1005: final byte getByteFromInt(int source) throws SqlException {
1006: if (Configuration.rangeCheckCrossConverters
1007: && (source > java.lang.Byte.MAX_VALUE || source < java.lang.Byte.MIN_VALUE)) {
1008: throw new LossOfPrecisionConversionException(
1009: agent_.logWriter_, String.valueOf(source));
1010: }
1011:
1012: return (byte) source;
1013: }
1014:
1015: final byte getByteFromLong(long source) throws SqlException {
1016: if (Configuration.rangeCheckCrossConverters
1017: && (source > java.lang.Byte.MAX_VALUE || source < java.lang.Byte.MIN_VALUE)) {
1018: throw new LossOfPrecisionConversionException(
1019: agent_.logWriter_, String.valueOf(source));
1020: }
1021:
1022: return (byte) source;
1023: }
1024:
1025: final byte getByteFromFloat(float source) throws SqlException {
1026: if (Configuration.rangeCheckCrossConverters
1027: && (source > java.lang.Byte.MAX_VALUE || source < java.lang.Byte.MIN_VALUE)) {
1028: throw new LossOfPrecisionConversionException(
1029: agent_.logWriter_, String.valueOf(source));
1030: }
1031:
1032: return (byte) source;
1033: }
1034:
1035: final byte getByteFromDouble(double source) throws SqlException {
1036: if (Configuration.rangeCheckCrossConverters
1037: && (source > java.lang.Byte.MAX_VALUE || source < java.lang.Byte.MIN_VALUE)) {
1038: throw new LossOfPrecisionConversionException(
1039: agent_.logWriter_, String.valueOf(source));
1040: }
1041:
1042: return (byte) source;
1043: }
1044:
1045: final byte getByteFromBigDecimal(java.math.BigDecimal source)
1046: throws SqlException {
1047: if (Configuration.rangeCheckCrossConverters
1048: && (source.compareTo(bdMaxByteValue__) == 1 || source
1049: .compareTo(bdMinByteValue__) == -1)) {
1050: throw new LossOfPrecisionConversionException(
1051: agent_.logWriter_, String.valueOf(source));
1052: }
1053: return (byte) source.intValue();
1054: }
1055:
1056: final byte getByteFromBoolean(boolean source) throws SqlException {
1057: return source ? (byte) 1 : (byte) 0;
1058: }
1059:
1060: final byte getByteFromString(String source) throws SqlException {
1061: try {
1062: return parseByte(source);
1063: } catch (java.lang.NumberFormatException e) {
1064: throw new SqlException(
1065: agent_.logWriter_,
1066: new ClientMessageId(SQLState.LANG_FORMAT_EXCEPTION),
1067: "byte", e);
1068: }
1069: }
1070:
1071: //---------------------------- getShort*() methods ---------------------------
1072:
1073: final short getShortFromInt(int source) throws SqlException {
1074: if (Configuration.rangeCheckCrossConverters
1075: && (source > java.lang.Short.MAX_VALUE || source < java.lang.Short.MIN_VALUE)) {
1076: throw new LossOfPrecisionConversionException(
1077: agent_.logWriter_, String.valueOf(source));
1078: }
1079:
1080: return (short) source;
1081: }
1082:
1083: final short getShortFromLong(long source) throws SqlException {
1084: if (Configuration.rangeCheckCrossConverters
1085: && (source > java.lang.Short.MAX_VALUE || source < java.lang.Short.MIN_VALUE)) {
1086: throw new LossOfPrecisionConversionException(
1087: agent_.logWriter_, String.valueOf(source));
1088: }
1089:
1090: return (short) source;
1091: }
1092:
1093: final short getShortFromFloat(float source) throws SqlException {
1094: if (Configuration.rangeCheckCrossConverters
1095: && (source > java.lang.Short.MAX_VALUE || source < java.lang.Short.MIN_VALUE)) {
1096: throw new LossOfPrecisionConversionException(
1097: agent_.logWriter_, String.valueOf(source));
1098: }
1099:
1100: return (short) source;
1101: }
1102:
1103: final short getShortFromDouble(double source) throws SqlException {
1104: if (Configuration.rangeCheckCrossConverters
1105: && (source > java.lang.Short.MAX_VALUE || source < java.lang.Short.MIN_VALUE)) {
1106: throw new LossOfPrecisionConversionException(
1107: agent_.logWriter_, String.valueOf(source));
1108: }
1109:
1110: return (short) source;
1111: }
1112:
1113: final short getShortFromBigDecimal(java.math.BigDecimal source)
1114: throws SqlException {
1115: if (Configuration.rangeCheckCrossConverters
1116: && (source.compareTo(bdMaxShortValue__) == 1 || source
1117: .compareTo(bdMinShortValue__) == -1)) {
1118: throw new LossOfPrecisionConversionException(
1119: agent_.logWriter_, String.valueOf(source));
1120: }
1121: return (short) source.intValue();
1122: }
1123:
1124: final short getShortFromBoolean(boolean source) throws SqlException {
1125: return source ? (short) 1 : (short) 0;
1126: }
1127:
1128: final short getShortFromString(String source) throws SqlException {
1129: try {
1130: return parseShort(source);
1131: } catch (java.lang.NumberFormatException e) {
1132: throw new SqlException(
1133: agent_.logWriter_,
1134: new ClientMessageId(SQLState.LANG_FORMAT_EXCEPTION),
1135: "short", e);
1136: }
1137: }
1138:
1139: //---------------------------- getInt*() methods -----------------------------
1140:
1141: final int getIntFromLong(long source) throws SqlException {
1142: if (Configuration.rangeCheckCrossConverters
1143: && (source > java.lang.Integer.MAX_VALUE || source < java.lang.Integer.MIN_VALUE)) {
1144: throw new LossOfPrecisionConversionException(
1145: agent_.logWriter_, String.valueOf(source));
1146: }
1147:
1148: return (int) source;
1149: }
1150:
1151: final int getIntFromFloat(float source) throws SqlException {
1152: if (Configuration.rangeCheckCrossConverters
1153: && (source > java.lang.Integer.MAX_VALUE || source < java.lang.Integer.MIN_VALUE)) {
1154: throw new LossOfPrecisionConversionException(
1155: agent_.logWriter_, String.valueOf(source));
1156: }
1157:
1158: return (int) source;
1159: }
1160:
1161: final int getIntFromDouble(double source) throws SqlException {
1162: if (Configuration.rangeCheckCrossConverters
1163: && (source > java.lang.Integer.MAX_VALUE || source < java.lang.Integer.MIN_VALUE)) {
1164: throw new LossOfPrecisionConversionException(
1165: agent_.logWriter_, String.valueOf(source));
1166: }
1167:
1168: return (int) source;
1169: }
1170:
1171: final int getIntFromBigDecimal(java.math.BigDecimal source)
1172: throws SqlException {
1173: if (Configuration.rangeCheckCrossConverters
1174: && (source.compareTo(bdMaxIntValue__) == 1 || source
1175: .compareTo(bdMinIntValue__) == -1)) {
1176: throw new LossOfPrecisionConversionException(
1177: agent_.logWriter_, String.valueOf(source));
1178: }
1179: return source.intValue();
1180: }
1181:
1182: final int getIntFromBoolean(boolean source) throws SqlException {
1183: return source ? (int) 1 : (int) 0;
1184: }
1185:
1186: final int getIntFromString(String source) throws SqlException {
1187: try {
1188: return parseInt(source);
1189: } catch (java.lang.NumberFormatException e) {
1190: throw new SqlException(
1191: agent_.logWriter_,
1192: new ClientMessageId(SQLState.LANG_FORMAT_EXCEPTION),
1193: "int", e);
1194: }
1195: }
1196:
1197: //---------------------------- getLong*() methods ----------------------------
1198:
1199: final long getLongFromFloat(float source) throws SqlException {
1200: if (Configuration.rangeCheckCrossConverters
1201: && (source > java.lang.Long.MAX_VALUE || source < java.lang.Long.MIN_VALUE)) {
1202: throw new LossOfPrecisionConversionException(
1203: agent_.logWriter_, String.valueOf(source));
1204: }
1205:
1206: return (long) source;
1207: }
1208:
1209: final long getLongFromDouble(double source) throws SqlException {
1210: if (Configuration.rangeCheckCrossConverters
1211: && (source > java.lang.Long.MAX_VALUE || source < java.lang.Long.MIN_VALUE)) {
1212: throw new LossOfPrecisionConversionException(
1213: agent_.logWriter_, String.valueOf(source));
1214: }
1215:
1216: return (long) source;
1217: }
1218:
1219: final long getLongFromBigDecimal(java.math.BigDecimal source)
1220: throws SqlException {
1221: if (Configuration.rangeCheckCrossConverters
1222: && (source.compareTo(bdMaxLongValue__) == 1 || source
1223: .compareTo(bdMinLongValue__) == -1)) {
1224: throw new LossOfPrecisionConversionException(
1225: agent_.logWriter_, String.valueOf(source));
1226: }
1227: return source.longValue();
1228: }
1229:
1230: final long getLongFromBoolean(boolean source) throws SqlException {
1231: return source ? (long) 1 : (long) 0;
1232: }
1233:
1234: final long getLongFromString(String source) throws SqlException {
1235: try {
1236: return parseLong(source);
1237: } catch (java.lang.NumberFormatException e) {
1238: throw new SqlException(
1239: agent_.logWriter_,
1240: new ClientMessageId(SQLState.LANG_FORMAT_EXCEPTION),
1241: "long", e);
1242: }
1243: }
1244:
1245: //---------------------------- getFloat*() methods ---------------------------
1246:
1247: final float getFloatFromDouble(double source) throws SqlException {
1248: if (Configuration.rangeCheckCrossConverters
1249: && Float.isInfinite((float) source)) {
1250: throw new LossOfPrecisionConversionException(
1251: agent_.logWriter_, String.valueOf(source));
1252: }
1253:
1254: return (float) source;
1255: }
1256:
1257: final float getFloatFromBigDecimal(java.math.BigDecimal source)
1258: throws SqlException {
1259: if (Configuration.rangeCheckCrossConverters
1260: && (source.compareTo(bdMaxFloatValue__) == 1 || source
1261: .compareTo(bdMinFloatValue__) == -1)) {
1262: throw new LossOfPrecisionConversionException(
1263: agent_.logWriter_, String.valueOf(source));
1264: }
1265: return source.floatValue();
1266: }
1267:
1268: final float getFloatFromBoolean(boolean source) throws SqlException {
1269: return source ? (float) 1 : (float) 0;
1270: }
1271:
1272: final float getFloatFromString(String source) throws SqlException {
1273: try {
1274: return Float.parseFloat(source.trim());
1275: } catch (java.lang.NumberFormatException e) {
1276: throw new SqlException(
1277: agent_.logWriter_,
1278: new ClientMessageId(SQLState.LANG_FORMAT_EXCEPTION),
1279: "float", e);
1280: }
1281: }
1282:
1283: //---------------------------- getDouble*() methods --------------------------
1284:
1285: final double getDoubleFromBigDecimal(java.math.BigDecimal source)
1286: throws SqlException {
1287: if (Configuration.rangeCheckCrossConverters
1288: && (source.compareTo(bdMaxDoubleValue__) == 1 || source
1289: .compareTo(bdMinDoubleValue__) == -1)) {
1290: throw new LossOfPrecisionConversionException(
1291: agent_.logWriter_, String.valueOf(source));
1292: }
1293: return source.doubleValue();
1294: }
1295:
1296: final double getDoubleFromBoolean(boolean source)
1297: throws SqlException {
1298: return source ? (double) 1 : (double) 0;
1299: }
1300:
1301: final double getDoubleFromString(String source) throws SqlException {
1302: try {
1303: return Double.parseDouble(source.trim());
1304: } catch (java.lang.NumberFormatException e) {
1305: throw new SqlException(
1306: agent_.logWriter_,
1307: new ClientMessageId(SQLState.LANG_FORMAT_EXCEPTION),
1308: "double", e);
1309: }
1310: }
1311:
1312: //---------------------------- getBigDecimal*() methods ----------------------
1313:
1314: final java.math.BigDecimal getBigDecimalFromBoolean(boolean source)
1315: throws SqlException {
1316: return source ? bdOne__ : bdZero__;
1317: }
1318:
1319: final java.math.BigDecimal getBigDecimalFromString(String source)
1320: throws SqlException {
1321: try {
1322: // Unfortunately, the big decimal constructor calls java.lang.Long.parseLong(),
1323: // which doesn't like spaces, so we have to call trim() to get rid of the spaces from CHAR columns.
1324: return new java.math.BigDecimal(source.trim());
1325: } catch (java.lang.NumberFormatException e) {
1326: throw new SqlException(
1327: agent_.logWriter_,
1328: new ClientMessageId(SQLState.LANG_FORMAT_EXCEPTION),
1329: "java.math.BigDecimal", e);
1330: }
1331: }
1332:
1333: //---------------------------- getString*() methods --------------------------
1334:
1335: final String getStringFromBoolean(boolean source)
1336: throws SqlException {
1337: return source ? "1" : "0";
1338: }
1339:
1340: final String getStringFromBytes(byte[] bytes) throws SqlException {
1341: StringBuffer stringBuffer = new StringBuffer(bytes.length * 2);
1342: for (int i = 0; i < bytes.length; i++) {
1343: String hexForByte = Integer.toHexString(bytes[i] & 0xff);
1344: // If the byte is x0-F, prepend a "0" in front to ensure 2 char representation
1345: if (hexForByte.length() == 1) {
1346: stringBuffer.append('0');
1347: }
1348: stringBuffer.append(hexForByte);
1349: }
1350: return stringBuffer.toString();
1351: }
1352:
1353: // All Numeric, and Date/Time types use String.valueOf (source)
1354:
1355: //---------------------------- getDate*() methods ----------------------------
1356:
1357: final java.sql.Date getDateFromString(String source)
1358: throws SqlException {
1359: try {
1360: return date_valueOf(source);
1361: } catch (java.lang.IllegalArgumentException e) { // subsumes NumberFormatException
1362: throw new SqlException(agent_.logWriter_,
1363: new ClientMessageId(
1364: SQLState.LANG_DATE_SYNTAX_EXCEPTION), e);
1365: }
1366: }
1367:
1368: final java.sql.Date getDateFromTime(java.sql.Time source)
1369: throws SqlException {
1370: return new java.sql.Date(source.getTime());
1371: }
1372:
1373: final java.sql.Date getDateFromTimestamp(java.sql.Timestamp source)
1374: throws SqlException {
1375: return new java.sql.Date(source.getTime());
1376: }
1377:
1378: //---------------------------- getTime*() methods ----------------------------
1379:
1380: final java.sql.Time getTimeFromString(String source)
1381: throws SqlException {
1382: try {
1383: return time_valueOf(source);
1384: } catch (java.lang.IllegalArgumentException e) { // subsumes NumberFormatException
1385: throw new SqlException(agent_.logWriter_,
1386: new ClientMessageId(
1387: SQLState.LANG_DATE_SYNTAX_EXCEPTION), e);
1388: }
1389: }
1390:
1391: final java.sql.Time getTimeFromTimestamp(java.sql.Timestamp source)
1392: throws SqlException {
1393: return new java.sql.Time(source.getTime());
1394: }
1395:
1396: //---------------------------- getTimestamp*() methods -----------------------
1397:
1398: final java.sql.Timestamp getTimestampFromString(String source)
1399: throws SqlException {
1400: try {
1401: return timestamp_valueOf(source);
1402: } catch (java.lang.IllegalArgumentException e) { // subsumes NumberFormatException
1403: throw new SqlException(agent_.logWriter_,
1404: new ClientMessageId(
1405: SQLState.LANG_DATE_SYNTAX_EXCEPTION), e);
1406: }
1407: }
1408:
1409: final java.sql.Timestamp getTimestampFromTime(java.sql.Time source)
1410: throws SqlException {
1411: return new java.sql.Timestamp(source.getTime());
1412: }
1413:
1414: final java.sql.Timestamp getTimestampFromDate(java.sql.Date source)
1415: throws SqlException {
1416: return new java.sql.Timestamp(source.getTime());
1417: }
1418:
1419: final java.sql.Date date_valueOf(String s)
1420: throws java.lang.IllegalArgumentException {
1421: String formatError = "JDBC Date format must be yyyy-mm-dd";
1422: if (s == null) {
1423: throw new java.lang.IllegalArgumentException(formatError);
1424: }
1425: s = s.trim();
1426: return java.sql.Date.valueOf(s);
1427: }
1428:
1429: final java.sql.Time time_valueOf(String s)
1430: throws java.lang.IllegalArgumentException,
1431: NumberFormatException {
1432: String formatError = "JDBC Time format must be hh:mm:ss";
1433: if (s == null) {
1434: throw new java.lang.IllegalArgumentException();
1435: }
1436: s = s.trim();
1437: return java.sql.Time.valueOf(s);
1438: }
1439:
1440: final java.sql.Timestamp timestamp_valueOf(String s)
1441: throws java.lang.IllegalArgumentException,
1442: NumberFormatException {
1443: String formatError = "JDBC Timestamp format must be yyyy-mm-dd hh:mm:ss.fffffffff";
1444: if (s == null) {
1445: throw new java.lang.IllegalArgumentException();
1446: }
1447:
1448: s = s.trim();
1449: return java.sql.Timestamp.valueOf(s);
1450: }
1451:
1452: private final byte parseByte(String s) throws NumberFormatException {
1453: int i = parseInt(s);
1454: if (i < Byte.MIN_VALUE || i > Byte.MAX_VALUE) {
1455: throw new NumberFormatException();
1456: }
1457: return (byte) i;
1458: }
1459:
1460: private final short parseShort(String s)
1461: throws NumberFormatException {
1462: int i = parseInt(s);
1463: if (i < Short.MIN_VALUE || i > Short.MAX_VALUE) {
1464: throw new NumberFormatException();
1465: }
1466: return (short) i;
1467: }
1468:
1469: // Custom version of java.lang.parseInt() that allows for space padding of char fields.
1470: private final int parseInt(String s) throws NumberFormatException {
1471: if (s == null) {
1472: throw new NumberFormatException("null");
1473: }
1474:
1475: int result = 0;
1476: boolean negative = false;
1477: int i = 0;
1478: int max = s.length();
1479: int limit;
1480: int multmin;
1481: int digit;
1482:
1483: if (max == 0) {
1484: throw new NumberFormatException(s);
1485: }
1486:
1487: if (s.charAt(0) == '-') {
1488: negative = true;
1489: limit = Integer.MIN_VALUE;
1490: i++;
1491: } else {
1492: limit = -Integer.MAX_VALUE;
1493: }
1494: multmin = limit / 10;
1495: // Special handle the first digit to get things started.
1496: if (i < max) {
1497: digit = Character.digit(s.charAt(i++), 10);
1498: if (digit < 0) {
1499: throw new NumberFormatException(s);
1500: } else {
1501: result = -digit;
1502: }
1503: }
1504: // Now handle all the subsequent digits or space padding.
1505: while (i < max) {
1506: char c = s.charAt(i++);
1507: if (c == ' ') {
1508: skipPadding(s, i, max);
1509: break;
1510: }
1511: // Accumulating negatively avoids surprises near MAX_VALUE
1512: digit = Character.digit(c, 10);
1513: if (digit < 0) {
1514: throw new NumberFormatException(s);
1515: }
1516: if (result < multmin) {
1517: throw new NumberFormatException(s);
1518: }
1519: result *= 10;
1520: if (result < limit + digit) {
1521: throw new NumberFormatException(s);
1522: }
1523: result -= digit;
1524: }
1525: if (negative) {
1526: if (i > 1) {
1527: return result;
1528: } else { // Only got "-"
1529: throw new NumberFormatException(s);
1530: }
1531: } else {
1532: return -result;
1533: }
1534: }
1535:
1536: private final long parseLong(String s) throws NumberFormatException {
1537: if (s == null) {
1538: throw new NumberFormatException("null");
1539: }
1540:
1541: long result = 0;
1542: boolean negative = false;
1543: int i = 0, max = s.length();
1544: long limit;
1545: long multmin;
1546: int digit;
1547:
1548: if (max == 0) {
1549: throw new NumberFormatException(s);
1550: }
1551:
1552: if (s.charAt(0) == '-') {
1553: negative = true;
1554: limit = Long.MIN_VALUE;
1555: i++;
1556: } else {
1557: limit = -Long.MAX_VALUE;
1558: }
1559: multmin = limit / 10;
1560: if (i < max) {
1561: digit = Character.digit(s.charAt(i++), 10);
1562: if (digit < 0) {
1563: throw new NumberFormatException(s);
1564: } else {
1565: result = -digit;
1566: }
1567: }
1568: while (i < max) {
1569: char c = s.charAt(i++);
1570: if (c == ' ') {
1571: skipPadding(s, i, max);
1572: break;
1573: }
1574: // Accumulating negatively avoids surprises near MAX_VALUE
1575: digit = Character.digit(c, 10);
1576: if (digit < 0) {
1577: throw new NumberFormatException(s);
1578: }
1579: if (result < multmin) {
1580: throw new NumberFormatException(s);
1581: }
1582: result *= 10;
1583: if (result < limit + digit) {
1584: throw new NumberFormatException(s);
1585: }
1586: result -= digit;
1587: }
1588: if (negative) {
1589: if (i > 1) {
1590: return result;
1591: } else { // Only got "-"
1592: throw new NumberFormatException(s);
1593: }
1594: } else {
1595: return -result;
1596: }
1597: }
1598:
1599: private final void skipPadding(String s, int i, int length)
1600: throws NumberFormatException {
1601: while (i < length) {
1602: if (s.charAt(i++) != ' ') {
1603: throw new NumberFormatException(s);
1604: }
1605: }
1606: }
1607: }
|