0001: /*
0002: * $Header: /cvsroot/webman-cms/source/webman/com/teamkonzept/db/TKSQLTypeConverter.java,v 1.7 2002/01/25 12:06:01 ralf Exp $
0003: *
0004: */
0005: package com.teamkonzept.db;
0006:
0007: import java.io.*;
0008: import java.math.*;
0009: import java.sql.*;
0010: import java.text.*;
0011: import java.util.Enumeration;
0012: import java.util.Hashtable;
0013:
0014: public class TKSQLTypeConverter {
0015: public static PrintStream LOG = System.out;
0016:
0017: public static final int HASHTABLE_SIZE = 19;
0018:
0019: public static int HASH_CODE = TKSQLTypeConverter.class.getName()
0020: .hashCode();
0021:
0022: final static Object[][] TYPE_NAMES_TABLE = {
0023: { new Integer(Types.BIGINT), "BIGINT" },
0024: { new Integer(Types.BINARY), "BINARY" },
0025: { new Integer(Types.BIT), "BIT" },
0026: { new Integer(Types.CHAR), "CHAR" },
0027: { new Integer(Types.DATE), "DATE" },
0028: { new Integer(Types.DECIMAL), "DECIMAL" },
0029: { new Integer(Types.DOUBLE), "DOUBLE" },
0030: { new Integer(Types.FLOAT), "FLOAT" },
0031: { new Integer(Types.INTEGER), "INTEGER" },
0032: { new Integer(Types.LONGVARBINARY), "LONGVARBINARY" },
0033: { new Integer(Types.LONGVARCHAR), "LONGVARCHAR" },
0034: { new Integer(Types.NUMERIC), "NUMERIC" },
0035: { new Integer(Types.REAL), "REAL" },
0036: { new Integer(Types.SMALLINT), "SMALLINT" },
0037: { new Integer(Types.TIME), "TIME" },
0038: { new Integer(Types.TIMESTAMP), "TIMESTAMP" },
0039: { new Integer(Types.TINYINT), "TINYINT" },
0040: { new Integer(Types.VARBINARY), "VARBINARY" },
0041: { new Integer(Types.VARCHAR), "VARCHAR" } };
0042: final static Hashtable TYPE_NAMES = initHash();
0043:
0044: static class TypeInfo {
0045:
0046: int DATA_TYPE;
0047:
0048: String LITERAL_PREFIX;
0049: String LITERAL_SUFFIX;
0050: int PRECISION;
0051: short MINIMUM_SCALE;
0052: short MAXIMUM_SCALE;
0053: boolean UNSIGNED_ATTRIBUTE;
0054: int NUM_PREC_RADIX;
0055:
0056: static int counter = 0;
0057:
0058: TypeInfo(final ResultSet rs) throws SQLException {
0059: DATA_TYPE = rs.getInt("DATA_TYPE");
0060: LITERAL_PREFIX = rs.getString("LITERAL_PREFIX");
0061: LITERAL_SUFFIX = rs.getString("LITERAL_SUFFIX");
0062: PRECISION = (int) rs.getLong("PRECISION");
0063: MINIMUM_SCALE = rs.getShort("MINIMUM_SCALE");
0064: MAXIMUM_SCALE = rs.getShort("MAXIMUM_SCALE");
0065: UNSIGNED_ATTRIBUTE = rs.getBoolean("UNSIGNED_ATTRIBUTE");
0066: NUM_PREC_RADIX = rs.getInt("NUM_PREC_RADIX");
0067: }
0068:
0069: TypeInfo(final int DATA_TYPE, final String LITERAL_PREFIX,
0070: final String LITERAL_SUFFIX, final int PRECISION,
0071: final int MINIMUM_SCALE, final int MAXIMUM_SCALE,
0072: final boolean UNSIGNED_ATTRIBUTE,
0073: final int NUM_PREC_RADIX) {
0074: this .DATA_TYPE = DATA_TYPE;
0075: this .LITERAL_PREFIX = LITERAL_PREFIX;
0076: this .LITERAL_SUFFIX = LITERAL_SUFFIX;
0077: this .PRECISION = PRECISION;
0078: this .MINIMUM_SCALE = (new Integer(MINIMUM_SCALE))
0079: .shortValue();
0080: this .MAXIMUM_SCALE = (new Integer(MAXIMUM_SCALE))
0081: .shortValue();
0082: this .UNSIGNED_ATTRIBUTE = UNSIGNED_ATTRIBUTE;
0083: this .NUM_PREC_RADIX = NUM_PREC_RADIX;
0084:
0085: }
0086:
0087: public boolean equals(final Object obj) {
0088: if (obj != null && getClass() == obj.getClass()) {
0089: return DATA_TYPE == ((TypeInfo) obj).DATA_TYPE;
0090: }
0091: return false;
0092: }
0093:
0094: public int hashCode() {
0095: return DATA_TYPE + HASH_CODE;
0096: }
0097:
0098: public String toString() {
0099: final String type_name = (String) TKSQLTypeConverter.TYPE_NAMES
0100: .get(new Integer(DATA_TYPE));
0101: return "TypeInfo( "
0102: + DATA_TYPE
0103: + (type_name != null ? " /* " + type_name + " */ "
0104: : "")
0105: + ",\t"
0106: + (LITERAL_PREFIX != null ? "\"" + LITERAL_PREFIX
0107: + "\"" : "null")
0108: + ",\t"
0109: + (LITERAL_SUFFIX != null ? "\"" + LITERAL_SUFFIX
0110: + "\"" : "null") + ",\t" + PRECISION
0111: + ",\t" + MINIMUM_SCALE + ",\t" + MAXIMUM_SCALE
0112: + ",\t" + UNSIGNED_ATTRIBUTE + ",\t"
0113: + NUM_PREC_RADIX + " )";
0114: }
0115: }
0116:
0117: protected final DatabaseMetaData meta_data;
0118: protected final Hashtable db_types = new Hashtable(HASHTABLE_SIZE);
0119:
0120: public TKSQLTypeConverter(final Connection conn)
0121: throws SQLException {
0122: this .meta_data = conn.getMetaData();
0123:
0124: /*
0125: * Lese die Beschreibung der von der DB unterst¸tzten
0126: * Datentypen aus.
0127: */
0128: final ResultSet type_rs = meta_data.getTypeInfo();
0129: while (type_rs.next()) {
0130:
0131: final TypeInfo db_type = new TypeInfo(type_rs);
0132: final Integer data_type = new Integer(db_type.DATA_TYPE);
0133: if (!db_types.containsKey(data_type))
0134: db_types.put(data_type, db_type);
0135: }
0136: type_rs.close();
0137: }
0138:
0139: protected TKSQLTypeConverter(final TypeInfo[] meta_data) {
0140: for (int i = 0; i < meta_data.length; i++) {
0141: final Integer data_type = new Integer(
0142: meta_data[i].DATA_TYPE);
0143: if (!db_types.containsKey(data_type))
0144: db_types.put(data_type, meta_data[i]);
0145: }
0146: this .meta_data = null;
0147: }
0148:
0149: /** liest den Array TYPE_NAMES_TABLE ein und erstellt daraus
0150: * eine Hashtable.
0151: *
0152: * @return TYPE_NAMES_TABLE als Hashtable
0153: */
0154: private static Hashtable initHash() {
0155: final Hashtable table = new Hashtable(TYPE_NAMES_TABLE.length);
0156:
0157: for (int i = 0; i < TYPE_NAMES_TABLE.length; i++) {
0158: table.put(TYPE_NAMES_TABLE[i][0], TYPE_NAMES_TABLE[i][1]);
0159: }
0160:
0161: return table;
0162: }
0163:
0164: /** Überprüfe, ob das DBMS die angegebene Konvertierung
0165: * mittels der CONVERT() Funktion erlaubt.
0166: *
0167: * @param int from_type JDBC-Quelltyp
0168: * @param int to_type JDBC-Zieltyp
0169: * @return true, falls die Konvertierung zulässig ist; false sonst
0170: */
0171: public boolean supportsConvert(final int from_type,
0172: final int to_type) throws SQLException {
0173: return meta_data.supportsConvert(from_type, to_type);
0174: }
0175:
0176: /** Versehe alle LITERAL_PREFIX u. -SUFFIX Strings mit
0177: * einem Escape-Zeichen (verdoppeln)
0178: *
0179: * @param String str der Eingabe-String, in dem alle Vorkomnisse
0180: * LITERAL_PREFIX u. -SUFFIX "geschützt" werden soll.
0181: * @param TypeInfo info DBMS-Typeninfo
0182: * @return <str> mit verdoppeltem LITERAL_PREFIX u. -SUFFIX'en
0183: */
0184: protected static String escapeQuotes(final String str,
0185: final TypeInfo info) {
0186:
0187: if (info.LITERAL_PREFIX != null) {
0188: final String buf = doubleQuotes(str, info.LITERAL_PREFIX);
0189:
0190: if (info.LITERAL_SUFFIX != null
0191: && !info.LITERAL_PREFIX.equals(info.LITERAL_SUFFIX)) {
0192: return doubleQuotes(buf, info.LITERAL_SUFFIX);
0193: } else {
0194: return buf;
0195: }
0196: } else if (info.LITERAL_SUFFIX != null) {
0197: return doubleQuotes(str, info.LITERAL_SUFFIX);
0198: } else {
0199: return str;
0200: }
0201: }
0202:
0203: /** Verdoppele alle Vorkommnisse des Strings <quote> im Eingabestring
0204: *
0205: * @param String literal der String, in dem alle Vorkomnisse
0206: * von <quote>-Strings verdoppelt werden soll
0207: * @param String quote die zu verdoppelnde Zeichenkette
0208: * @return <literal> mit verdoppeltem <qoute>'s
0209: */
0210: protected static String doubleQuotes(final String literal,
0211: final String quote) {
0212: final StringBuffer buf = new StringBuffer();
0213:
0214: int start = 0;
0215: int end;
0216: while ((end = literal.indexOf(quote, start)) > 0) {
0217: buf.append(literal.substring(start, end) + quote + quote);
0218: start = end + 1;
0219: }
0220: buf.append(literal.substring(start, literal.length()));
0221:
0222: return buf.toString();
0223: }
0224:
0225: /** Erzeuge ein Stringliteral, d.h. fasse den String in
0226: * LITERAL_PREFIX u. -_SUFFIX ein.
0227: *
0228: * @param TypeInfo info Typenbeshreibung
0229: * @param String str der zu konvertierenden String
0230: * @return SQL-Stringliteral
0231: */
0232: protected static String createStringLiteral(final TypeInfo info,
0233: final String str) {
0234: final StringBuffer result = new StringBuffer();
0235:
0236: if (info.LITERAL_PREFIX != null)
0237: result.append(info.LITERAL_PREFIX);
0238:
0239: result.append(escapeQuotes(str, info));
0240:
0241: if (info.LITERAL_SUFFIX != null)
0242: result.append(info.LITERAL_SUFFIX);
0243:
0244: return result.toString();
0245: }
0246:
0247: /** Erzeugt eine NumberFormat-Klasse für den angegeben JDBC-Typen.
0248: * Je nach Typen, wird Prefix, Suffix und Genauigkeit der
0249: * NumberFormat-Klasse gesetzt.
0250: *
0251: * @param int type JDBC-Zieltyp (java.sql.Types)
0252: * @return die entsprechende NumberFormat-Klasse
0253: *
0254: * @see java.text.NumberFormat
0255: * @see java.text.DecimalFormat
0256: */
0257: protected static NumberFormat getNumberFormat(final TypeInfo info) {
0258: // Format-Symbole setzen
0259: final DecimalFormatSymbols symbols = new DecimalFormatSymbols();
0260: symbols.setMinusSign('-');
0261: symbols.setDecimalSeparator('.');
0262: symbols.setZeroDigit('0');
0263:
0264: // Zahlen-Muster setzen
0265: final StringBuffer pattern = new StringBuffer();
0266: if (info.LITERAL_PREFIX != null)
0267: pattern.append(info.LITERAL_PREFIX);
0268: pattern.append("#.#");
0269: if (info.LITERAL_SUFFIX != null)
0270: pattern.append(info.LITERAL_SUFFIX);
0271:
0272: // Formatklasse erzeugen
0273: final DecimalFormat format = new DecimalFormat(pattern
0274: .toString(), symbols);
0275: format.setMinimumFractionDigits(info.MINIMUM_SCALE);
0276: format.setMaximumFractionDigits(info.MAXIMUM_SCALE);
0277: format.setMinimumIntegerDigits(0);
0278: format.setMaximumIntegerDigits(info.PRECISION
0279: - info.MINIMUM_SCALE);
0280: format.setGroupingUsed(false);
0281:
0282: return format;
0283: }
0284:
0285: /** Versucht eine geeignete Konvertierung für die gegebene
0286: * Zahl <num> zu finden. Es wird erst nach einer vom DBMS
0287: * unterstützten Konvertierung gesucht, wobei der Reihe nach
0288: * jeweils eine Konvertierung der Form
0289: * <num> -> <from_types[0]> -> to_type, ..., <num> -> <from_types[n]> -> to_type
0290: * gesucht wird. Erst danach wird <num> in <from_types[0]> konvertiert
0291: * und von da aus in <to_type>.
0292: *
0293: * @param int[] from_types Liste von möglichen JDBC-Typen, in die
0294: * <num> umgewandelt werden kann, um von da aus in
0295: * <to_type> konvertiert zu werden.
0296: * @param int to_type JDBC-Zieltyp
0297: * @param Number num die zu konvertierende Zahl
0298: * @return SQL-Textrepräsentation der in den JDBC-Typ
0299: * umgewandelten Zahl. Dies kann gegebenfalls
0300: * auch ein String der Form "CONVERT( type, value )" sein.
0301: *
0302: * @see java.sql.DatabaseMetaData#supportsConvert
0303: * @see java.sql.Types
0304: */
0305: protected String standardNumberConversion(final int[] from_types,
0306: final int to_type, final Number num) throws SQLException,
0307: TKIllegalConversionException {
0308: for (int i = 0; i < from_types.length; i++) {
0309: if (supportsConvert(from_types[i], to_type)) {
0310: final TypeInfo info = (TypeInfo) db_types
0311: .get(new Integer(from_types[i]));
0312: final String type_name = (String) TYPE_NAMES
0313: .get(new Integer(to_type));
0314: final String literal = createNumberLiteral(info, num);
0315: ;
0316:
0317: return "{fn CONVERT(" + literal + ", " + type_name
0318: + ") }";
0319: }
0320: }
0321:
0322: final TypeInfo info = (TypeInfo) db_types.get(new Integer(
0323: from_types[0]));
0324:
0325: switch (to_type) {
0326:
0327: case Types.CHAR:
0328: case Types.VARCHAR:
0329: case Types.LONGVARCHAR:
0330: return createStringLiteral(info, createNumberLiteral(info,
0331: num));
0332:
0333: case Types.BIT:
0334: final boolean state;
0335:
0336: if (num instanceof BigDecimal || num instanceof Float
0337: || num instanceof Double)
0338: state = num.doubleValue() != 0 ? true : false;
0339: else
0340: state = num.longValue() != 0 ? true : false;
0341:
0342: return createBitLiteral(info, state);
0343:
0344: default:
0345: throw new TKIllegalConversionException(num.getClass()
0346: .getName(), "java.sql."
0347: + TYPE_NAMES.get(new Integer(to_type)));
0348: }
0349: }
0350:
0351: /** Erzeuge ein Zahlen-Literal, d.h. fasse die
0352: * SQL-Textrepräsentation der Zahl in
0353: * LITERAL_PREFIX u. -_SUFFIX ein
0354: *
0355: * @param TypeInfo info DBMS-Typenbeshreibung
0356: * @param Number num Die umzuwandelnde Zahl
0357: * @return SQL-Textrepräsentation
0358: */
0359: protected static String createNumberLiteral(final TypeInfo info,
0360: final Number num) {
0361: switch (info.DATA_TYPE) {
0362:
0363: case Types.NUMERIC:
0364: case Types.DECIMAL:
0365: if (num instanceof BigDecimal) {
0366: BigDecimal dec = (BigDecimal) num;
0367: final int scale = dec.scale();
0368:
0369: if (scale < info.MINIMUM_SCALE)
0370: dec = dec.setScale(info.MINIMUM_SCALE);
0371: else if (scale > info.MAXIMUM_SCALE)
0372: dec = dec.setScale(info.MAXIMUM_SCALE,
0373: BigDecimal.ROUND_HALF_DOWN);
0374:
0375: final StringBuffer literal = new StringBuffer();
0376: if (info.LITERAL_PREFIX != null)
0377: literal.append(info.LITERAL_PREFIX);
0378: literal.append(dec.toString());
0379: if (info.LITERAL_SUFFIX != null)
0380: literal.append(info.LITERAL_SUFFIX);
0381: return literal.toString();
0382: }
0383:
0384: case Types.FLOAT:
0385: case Types.DOUBLE:
0386: case Types.REAL:
0387: return getNumberFormat(info).format(num.doubleValue());
0388:
0389: default:
0390: return getNumberFormat(info).format(num.longValue());
0391: }
0392: }
0393:
0394: /** Erzeuge ein Bitliteral, d.h. fasse die
0395: * SQL-Textrepräsentation des Bool'schen-Wertes (=0|1) in
0396: * LITERAL_PREFIX u. -_SUFFIX ein.
0397: *
0398: * @param TypeInfo info DBMS-Typenbeshreibung
0399: * @param boolean state Der umzuwandelnde Bool'sche Wert
0400: * @return SQL-Textrepräsentation
0401: */
0402: protected static String createBitLiteral(final TypeInfo info,
0403: final boolean state) {
0404: final StringBuffer literal = new StringBuffer();
0405:
0406: if (info.LITERAL_PREFIX != null)
0407: literal.append(info.LITERAL_PREFIX);
0408:
0409: literal.append(state ? "1" : "0");
0410:
0411: if (info.LITERAL_SUFFIX != null)
0412: literal.append(info.LITERAL_SUFFIX);
0413:
0414: return literal.toString();
0415: }
0416:
0417: /** Erzeuge ein Bytestringliteral, d.h. fasse die
0418: * SQL-Textrepräsentation (Hexadezimaldarst.) des Byte-Arrays in
0419: * LITERAL_PREFIX u. -_SUFFIX ein.
0420: *
0421: * @param TypeInfo info DBMS-Typenbeshreibung
0422: * @param Byte[] data Der umzuwandelnde Byte-Array
0423: * @return SQL-Textrepräsentation
0424: */
0425: protected static String createBytestringLiteral(
0426: final TypeInfo info, final Byte[] data) {
0427: final StringBuffer literal = new StringBuffer();
0428:
0429: if (info.LITERAL_PREFIX != null)
0430: literal.append(info.LITERAL_PREFIX);
0431:
0432: for (int i = 0; i < data.length; i++)
0433: literal.append(Integer.toHexString(data[i].intValue()));
0434:
0435: if (info.LITERAL_SUFFIX != null)
0436: literal.append(info.LITERAL_SUFFIX);
0437:
0438: return literal.toString();
0439: }
0440:
0441: /** Erzeuge ein Datumsliteral, d.h. schreibe das Datum, als
0442: * SQL Escape Statement
0443: *
0444: * @param Date date das umzuwandelnde Datum
0445: * @return SQL-Textrepräsentation
0446: */
0447: protected static String createDateLiteral(final java.sql.Date date) {
0448: return "{d '" + date.toString() + "'}";
0449: }
0450:
0451: /** Erzeuge ein Timeliteral, d.h. schreibe die Zeit, als
0452: * SQL Escape Statement
0453: *
0454: * @param Time time das umzuwandelnde Zeitobjekt
0455: * @return SQL-Textrepräsentation
0456: */
0457: protected static String createTimeLiteral(final Time time) {
0458: return "{t '" + time.toString() + "'}";
0459: }
0460:
0461: /** Erzeuge ein Timestampliteral, d.h. schreibe den Zeitstempel, als
0462: * SQL Escape Statement
0463: *
0464: * @param Timestamp timestamp das umzuwandelnde Zeitstempelobjekt
0465: * @return SQL-Textrepräsentation
0466: */
0467: protected static String createTimestampLiteral(
0468: final Timestamp timestamp) {
0469: return "{ts '" + timestamp.toString() + "'}";
0470: }
0471:
0472: /** "Frontend"-Methode zu den restlichen convertXXX()-Methoden.
0473: * Liefert die SQL-Textrepräsentation des Objektes
0474: * im gewüschten Typ.
0475: *
0476: * @param int type JDBC-Zieltyp
0477: * @param Object obj das zu konvertierende Objekt
0478: *
0479: * @return SQL-Textrepräsentation des in den JDBC-Typ
0480: * umgewandelten Objektes. Dies kann gegebenfalls
0481: * auch ein String der Form "CONVERT( type, value )" sein.
0482: *
0483: * @see java.sql.Types
0484: */
0485: public String convert(final int type, final Object obj)
0486: throws SQLException, TKIllegalConversionException {
0487: if (obj instanceof String)
0488: return convertString(type, (String) obj);
0489:
0490: if (obj instanceof BigDecimal)
0491: return convertBigDecimal(type, (BigDecimal) obj);
0492:
0493: if (obj instanceof Boolean)
0494: return convertBoolean(type, (Boolean) obj);
0495:
0496: if (obj instanceof Byte)
0497: return convertByte(type, (Byte) obj);
0498:
0499: if (obj instanceof Short)
0500: return convertShort(type, (Short) obj);
0501:
0502: if (obj instanceof Integer)
0503: return convertInteger(type, (Integer) obj);
0504:
0505: if (obj instanceof Long)
0506: return convertLong(type, (Long) obj);
0507:
0508: if (obj instanceof Float)
0509: return convertFloat(type, (Float) obj);
0510:
0511: if (obj instanceof Double)
0512: return convertDouble(type, (Double) obj);
0513:
0514: if (obj instanceof Byte[])
0515: return convertByteArray(type, (Byte[]) obj);
0516:
0517: if (obj instanceof java.sql.Date)
0518: return convertDate(type, (java.sql.Date) obj);
0519:
0520: if (obj instanceof Time)
0521: return convertTime(type, (Time) obj);
0522:
0523: if (obj instanceof Timestamp)
0524: return convertTimestamp(type, (Timestamp) obj);
0525:
0526: throw new TKIllegalConversionException(
0527: obj.getClass().getName(), "java.sql."
0528: + TYPE_NAMES.get(new Integer(type)));
0529: }
0530:
0531: /** "Generische" Methode zur Konvertierung von Zahlen-Objekten.
0532: * Erzeugt ein Zahlenliteral, falls nur in ein anderen Zahlentyp
0533: * konvertiert werden soll, ansonsten wird auf die Methode
0534: * standardNumberConversion() zurückgegriffen.
0535: *
0536: * @param int[] from_types Liste von möglichen JDBC-Typen, in die
0537: * <num> umgewandelt werden kann, um von da aus in
0538: * <to_type> konvertiert zu werden.
0539: * @param int to_type JDBC-Zieltyp
0540: *
0541: * @return SQL-Textrepräsentation der in den JDBC-Typ
0542: * umgewandelten Zahl. Dies kann gegebenfalls
0543: * auch ein String der Form "CONVERT( type, value )" sein.
0544: *
0545: * @see com.teamkonzept.db.TKSQLTypeConverter.standardNumberConversion
0546: * @see java.sql.Types
0547: */
0548: protected String convertNumber(final int[] from_types,
0549: final int to_type, final Number num) throws SQLException,
0550: TKIllegalConversionException {
0551: final TypeInfo type_info = (TypeInfo) db_types.get(new Integer(
0552: to_type));
0553: if (type_info == null)
0554: throw new TKIllegalConversionException(num.getClass()
0555: .getName(), "JDBC-Type java.sql.Types."
0556: + TYPE_NAMES.get(new Integer(to_type)));
0557:
0558: switch (to_type) {
0559:
0560: case Types.NUMERIC:
0561: case Types.DECIMAL:
0562: case Types.DOUBLE:
0563: case Types.FLOAT:
0564: case Types.REAL:
0565: case Types.INTEGER:
0566: case Types.BIGINT:
0567: case Types.SMALLINT:
0568: case Types.TINYINT:
0569: return createNumberLiteral(type_info, num);
0570:
0571: default:
0572: /* Versuche, ob eine Konvertierung mittels der
0573: * DBMS-CONVERT-Funktion mˆglich ist, ansonsten
0574: * verwende, soweit mˆglich, eine eigene Konvertierung,
0575: * oder werfe eine Exception
0576: */
0577: return standardNumberConversion(from_types, to_type, num);
0578: }
0579: }
0580:
0581: /** Konvertiert ein String Objekt in den angegeben JDBC-Typ und
0582: * liefert dessen SQL-Textrepräsentation.
0583: *
0584: * @param int type JDBC-Zieltyp (java.sql.Types)
0585: * @param String str der zu konvertierenden String
0586: * @return SQL-Textrepräsentation des in den JDBC-Typ
0587: * umgewandelten Eingabestrings. Dies kann gegebenfalls
0588: * auch ein String der Form "CONVERT( type, value )" sein.
0589: *
0590: * @see java.sql.DatabaseMetaData#supportsConvert
0591: * @see java.sql.Types
0592: */
0593: public String convertString(final int type, final String str)
0594: throws SQLException, TKIllegalConversionException {
0595: final TypeInfo type_info = (TypeInfo) db_types.get(new Integer(
0596: type));
0597: if (type_info == null)
0598: throw new TKIllegalConversionException("java.lang.String",
0599: "JDBC-Type java.sql.Types."
0600: + TYPE_NAMES.get(new Integer(type)));
0601:
0602: switch (type) {
0603:
0604: case Types.CHAR:
0605: case Types.VARCHAR:
0606: case Types.LONGVARCHAR:
0607: return createStringLiteral(type_info, str);
0608:
0609: default:
0610:
0611: /* Versuche, ob eine Konvertierung mittels der
0612: * DBMS-CONVERT-Funktion mˆglich ist, ansonsten
0613: * gib den String, so wie er ist zur¸ck
0614: */
0615: final int[] from_types = { Types.CHAR, Types.VARCHAR,
0616: Types.LONGVARCHAR };
0617: for (int i = 0; i < from_types.length; i++) {
0618: if (supportsConvert(from_types[i], type)) {
0619: final TypeInfo info = (TypeInfo) db_types
0620: .get(new Integer(from_types[i]));
0621: final String literal = createStringLiteral(info,
0622: str);
0623: final String type_name = (String) TYPE_NAMES
0624: .get(new Integer(type));
0625:
0626: return "{fn CONVERT( " + literal + ", " + type_name
0627: + ") }";
0628: }
0629: }
0630:
0631: return str;
0632: }
0633: }
0634:
0635: /** Konvertiert ein Bool'schen Wert in den angegeben JDBC-Typ und
0636: * liefert dessen SQL-Textrepräsentation.
0637: *
0638: * @param int type JDBC-Zieltyp (java.sql.Types)
0639: * @param BigDecimal num die zu konvertierenden Bool'sche Wert
0640: * @return SQL-Textrepräsentation des in den JDBC-Typ
0641: * umgewandelten Bool'sche Wert. Dies kann gegebenfalls
0642: * auch ein String der Form "CONVERT( type, value )" sein.
0643: *
0644: * @see java.sql.DatabaseMetaData#supportsConvert
0645: * @see java.sql.Types
0646: */
0647: public String convertBoolean(final int type, final Boolean state)
0648: throws SQLException, TKIllegalConversionException {
0649: final TypeInfo type_info = (TypeInfo) db_types.get(new Integer(
0650: type));
0651: if (type_info == null)
0652: throw new TKIllegalConversionException("java.lang.Boolean",
0653: "JDBC-Type java.sql.Types."
0654: + TYPE_NAMES.get(new Integer(type)));
0655:
0656: switch (type) {
0657:
0658: case Types.BIT:
0659: return createBitLiteral(type_info, state.booleanValue());
0660:
0661: default:
0662: if (supportsConvert(Types.BIT, type)) {
0663: final String type_name = (String) TYPE_NAMES
0664: .get(new Integer(type));
0665:
0666: return "{fn CONVERT( "
0667: + createBitLiteral(type_info, state
0668: .booleanValue()) + ", " + type_name
0669: + ") }";
0670: } else {
0671: throw new TKIllegalConversionException(
0672: "java.lang.Boolean",
0673: "JDBC-Type java.sql.Types."
0674: + TYPE_NAMES.get(new Integer(type)));
0675: }
0676: }
0677: }
0678:
0679: /** Konvertiert ein byte in den angegeben JDBC-Typ und
0680: * liefert dessen SQL-Textrepräsentation.
0681: *
0682: * @param int type JDBC-Zieltyp (java.sql.Types)
0683: * @param Byte num der zu konvertierenden Byte Wert
0684: * @return SQL-Textrepräsentation des in den JDBC-Typen
0685: * umgewandelten Byte-Wertes. Dies kann gegebenfalls
0686: * auch ein String der Form "CONVERT( type, value )" sein.
0687: *
0688: * @see java.sql.DatabaseMetaData#supportsConvert
0689: * @see java.sql.Types
0690: */
0691: public String convertByte(final int type, final Byte num)
0692: throws SQLException, TKIllegalConversionException {
0693: final int[] from_types = { Types.TINYINT, Types.SMALLINT,
0694: Types.INTEGER, Types.BIGINT, Types.FLOAT, Types.DOUBLE,
0695: Types.REAL, Types.NUMERIC, Types.DECIMAL };
0696: return convertNumber(from_types, type, num);
0697: }
0698:
0699: /** Konvertiert ein Bytearray in den angegeben JDBC-Typ und
0700: * liefert dessen SQL-Textrepräsentation.
0701: *
0702: * @param int type JDBC-Zieltyp (java.sql.Types)
0703: * @param Byte[] data der zu konvertierenden Byte Wert
0704: * @return SQL-Textrepräsentation des in den JDBC-Typen
0705: * umgewandelten Byte-Feldes. Dies kann gegebenfalls
0706: * auch ein String der Form "CONVERT( type, value )" sein.
0707: *
0708: * @see java.sql.DatabaseMetaData#supportsConvert
0709: * @see java.sql.Types
0710: */
0711: public String convertByteArray(final int type, final Byte[] data)
0712: throws SQLException, TKIllegalConversionException {
0713: final TypeInfo type_info = (TypeInfo) db_types.get(new Integer(
0714: type));
0715: if (type_info == null)
0716: throw new TKIllegalConversionException("java.lang.Byte[]",
0717: "JDBC-Type java.sql.Types."
0718: + TYPE_NAMES.get(new Integer(type)));
0719:
0720: switch (type) {
0721:
0722: case Types.BINARY:
0723: case Types.VARBINARY:
0724: case Types.LONGVARBINARY:
0725: return createBytestringLiteral(type_info, data);
0726:
0727: default:
0728:
0729: final int[] from_types = { Types.BINARY, Types.VARBINARY,
0730: Types.LONGVARBINARY };
0731:
0732: for (int i = 0; i < from_types.length; i++) {
0733: if (supportsConvert(from_types[i], type)) {
0734: final TypeInfo info = (TypeInfo) db_types
0735: .get(new Integer(from_types[i]));
0736: final String type_name = (String) TYPE_NAMES
0737: .get(new Integer(type));
0738: final String literal = createBytestringLiteral(
0739: info, data);
0740:
0741: return "{fn CONVERT( " + literal + ", " + type_name
0742: + ") }";
0743: }
0744: }
0745: throw new TKIllegalConversionException("java.lang.Byte[]",
0746: "JDBC-Type java.sql.Types."
0747: + TYPE_NAMES.get(new Integer(type)));
0748: }
0749: }
0750:
0751: /** Konvertiert ein Short-Wert in den angegeben JDBC-Typ und
0752: * liefert dessen SQL-Textrepräsentation.
0753: *
0754: * @param int type JDBC-Zieltyp (java.sql.Types)
0755: * @param Short num der zu konvertierenden Short-Wert
0756: * @return SQL-Textrepräsentation des in den JDBC-Typen
0757: * umgewandelten Short-Wertes. Dies kann gegebenfalls
0758: * auch ein String der Form "CONVERT( type, value )" sein.
0759: *
0760: * @see java.sql.DatabaseMetaData#supportsConvert
0761: * @see java.sql.Types
0762: */
0763: public String convertShort(final int type, final Short num)
0764: throws SQLException, TKIllegalConversionException {
0765: final int[] from_types = { Types.SMALLINT, Types.INTEGER,
0766: Types.BIGINT, Types.FLOAT, Types.DOUBLE, Types.REAL,
0767: Types.NUMERIC, Types.DECIMAL };
0768: return convertNumber(from_types, type, num);
0769: }
0770:
0771: /** Konvertiert ein Integer-Wert in den angegeben JDBC-Typ und
0772: * liefert dessen SQL-Textrepräsentation.
0773: *
0774: * @param int type JDBC-Zieltyp (java.sql.Types)
0775: * @param Integer num der zu konvertierenden Integer-Wert
0776: * @return SQL-Textrepräsentation des in den JDBC-Typen
0777: * umgewandelten Integer-Wertes. Dies kann gegebenfalls
0778: * auch ein String der Form "CONVERT( type, value )" sein.
0779: *
0780: * @see java.sql.DatabaseMetaData#supportsConvert
0781: * @see java.sql.Types
0782: */
0783: public String convertInteger(final int type, final Integer num)
0784: throws SQLException, TKIllegalConversionException {
0785: final int[] from_types = { Types.INTEGER, Types.BIGINT,
0786: Types.FLOAT, Types.DOUBLE, Types.REAL, Types.NUMERIC,
0787: Types.DECIMAL };
0788: return convertNumber(from_types, type, num);
0789: }
0790:
0791: /** Konvertiert ein Long-Wert in den angegeben JDBC-Typ und
0792: * liefert dessen SQL-Textrepräsentation.
0793: *
0794: * @param int type JDBC-Zieltyp (java.sql.Types)
0795: * @param Long num der zu konvertierenden Float-Wert
0796: * @return SQL-Textrepräsentation des in den JDBC-Typen
0797: * umgewandelten Long-Wertes. Dies kann gegebenfalls
0798: * auch ein String der Form "CONVERT( type, value )" sein.
0799: *
0800: * @see java.sql.DatabaseMetaData#supportsConvert
0801: * @see java.sql.Types
0802: */
0803: public String convertLong(final int type, final Long num)
0804: throws SQLException, TKIllegalConversionException {
0805: final int[] from_types = { Types.BIGINT, Types.FLOAT,
0806: Types.DOUBLE, Types.REAL, Types.NUMERIC, Types.DECIMAL };
0807: return convertNumber(from_types, type, num);
0808: }
0809:
0810: /** Konvertiert ein Float-Wert in den angegeben JDBC-Typ und
0811: * liefert dessen SQL-Textrepräsentation.
0812: *
0813: * @param int type JDBC-Zieltyp (java.sql.Types)
0814: * @param Float num der zu konvertierenden Float-Wert
0815: * @return SQL-Textrepräsentation des in den JDBC-Typen
0816: * umgewandelten Float-Wertes. Dies kann gegebenfalls
0817: * auch ein String der Form "CONVERT( type, value )" sein.
0818: *
0819: * @see java.sql.DatabaseMetaData#supportsConvert
0820: * @see java.sql.Types
0821: */
0822: public String convertFloat(final int type, final Float num)
0823: throws SQLException, TKIllegalConversionException {
0824: final int[] from_types = { Types.FLOAT, Types.DOUBLE,
0825: Types.REAL, Types.NUMERIC, Types.DECIMAL };
0826: return convertNumber(from_types, type, num);
0827: }
0828:
0829: /** Konvertiert ein Double-Wert in den angegeben JDBC-Typ und
0830: * liefert dessen SQL-Textrepräsentation.
0831: *
0832: * @param int type JDBC-Zieltyp (java.sql.Types)
0833: * @param Double num der zu konvertierenden Double-Wert
0834: * @return SQL-Textrepräsentation des in den JDBC-Typen
0835: * umgewandelten Double-Wertes. Dies kann gegebenfalls
0836: * auch ein String der Form "CONVERT( type, value )" sein.
0837: *
0838: * @see java.sql.DatabaseMetaData#supportsConvert
0839: * @see java.sql.Types
0840: */
0841: public String convertDouble(final int type, final Double num)
0842: throws SQLException, TKIllegalConversionException {
0843: final int[] from_types = { Types.DOUBLE, Types.REAL,
0844: Types.NUMERIC, Types.DECIMAL };
0845: return convertNumber(from_types, type, num);
0846: }
0847:
0848: /** Konvertiert ein BigDecimal Objekt in den angegeben JDBC-Typ und
0849: * liefert dessen SQL-Textrepräsentation.
0850: *
0851: * @param int type JDBC-Zieltyp (java.sql.Types)
0852: * @param BigDecimal num die zu konvertierenden BigDecimal-Zahl
0853: * @return SQL-Textrepräsentation der in den JDBC-Typ
0854: * umgewandelten BigDecimal-Zahl. Dies kann gegebenfalls
0855: * auch ein String der Form "CONVERT( type, value )" sein.
0856: *
0857: * @see java.sql.DatabaseMetaData#supportsConvert
0858: * @see java.sql.Types
0859: * @see java.math.BigDecimal
0860: */
0861: public String convertBigDecimal(final int type, final BigDecimal num)
0862: throws SQLException, TKIllegalConversionException {
0863: final int[] from_types = { Types.NUMERIC, Types.DECIMAL };
0864:
0865: return convertNumber(from_types, type, num);
0866: }
0867:
0868: /** Konvertiert ein java.sql.Date Objekt in den angegeben JDBC-Typ und
0869: * liefert dessen SQL-Textrepräsentation.
0870: *
0871: * @param int type JDBC-Zieltyp (java.sql.Types)
0872: * @param Date date das zu konvertierenden Datumsobjekt
0873: * @return SQL-Textrepräsentation des in den JDBC-Typ
0874: * umgewandelten Datums. Dies kann gegebenfalls
0875: * auch ein String der Form "CONVERT( type, value )" sein.
0876: *
0877: * @see java.sql.DatabaseMetaData#supportsConvert
0878: * @see java.sql.Types
0879: * @see java.sql.Date
0880: */
0881: public String convertDate(final int type, final java.sql.Date date)
0882: throws SQLException, TKIllegalConversionException {
0883: if (type == Types.DATE) {
0884: return createDateLiteral(date);
0885: }
0886:
0887: final TypeInfo type_info = (TypeInfo) db_types.get(new Integer(
0888: type));
0889: if (type_info == null)
0890: throw new TKIllegalConversionException("java.sql.Date",
0891: "JDBC-Type java.sql.Types."
0892: + TYPE_NAMES.get(new Integer(type)));
0893:
0894: if (supportsConvert(Types.DATE, type)) {
0895: final String type_name = (String) TYPE_NAMES
0896: .get(new Integer(type));
0897:
0898: return "{fn CONVERT( " + createDateLiteral(date) + ", "
0899: + type_name + ") }";
0900: } else {
0901: throw new TKIllegalConversionException("java.sql.Date",
0902: "JDBC-Type java.sql.Types."
0903: + TYPE_NAMES.get(new Integer(type)));
0904: }
0905: }
0906:
0907: /** Konvertiert ein java.sql.Time Objekt in den angegeben JDBC-Typ und
0908: * liefert dessen SQL-Textrepräsentation.
0909: *
0910: * @param int type JDBC-Zieltyp (java.sql.Types)
0911: * @param Time time das zu konvertierenden Zeitobjekt
0912: * @return SQL-Textrepräsentation der in den JDBC-Typ
0913: * umgewandelten Zeit. Dies kann gegebenfalls
0914: * auch ein String der Form "CONVERT( type, value )" sein.
0915: *
0916: * @see java.sql.DatabaseMetaData#supportsConvert
0917: * @see java.sql.Types
0918: * @see java.sql.Time
0919: */
0920: public String convertTime(final int type, final Time time)
0921: throws SQLException, TKIllegalConversionException {
0922: if (type == Types.TIME) {
0923: return createTimeLiteral(time);
0924: }
0925:
0926: final TypeInfo type_info = (TypeInfo) db_types.get(new Integer(
0927: type));
0928: if (type_info == null)
0929: throw new TKIllegalConversionException("java.sql.Time",
0930: "JDBC-Type java.sql.Types."
0931: + TYPE_NAMES.get(new Integer(type)));
0932:
0933: if (supportsConvert(Types.TIME, type)) {
0934: final String type_name = (String) TYPE_NAMES
0935: .get(new Integer(type));
0936:
0937: return "{fn CONVERT( " + createTimeLiteral(time) + ", "
0938: + type_name + ") }";
0939: } else {
0940: throw new TKIllegalConversionException("java.sql.Time",
0941: "java.sql." + TYPE_NAMES.get(new Integer(type)));
0942: }
0943: }
0944:
0945: /** Konvertiert ein java.sql.Timestamp Objekt in den angegeben JDBC-Typ und
0946: * liefert dessen SQL-Textrepräsentation.
0947: *
0948: * @param int type JDBC-Zieltyp (java.sql.Types)
0949: * @param Timestamp timestamp das zu konvertierenden Zeitstempelobjekt
0950: * @return SQL-Textrepräsentation der in den JDBC-Typ
0951: * umgewandelten Zeit. Dies kann gegebenfalls
0952: * auch ein String der Form "CONVERT( type, value )" sein.
0953: *
0954: * @see java.sql.DatabaseMetaData#supportsConvert
0955: * @see java.sql.Types
0956: * @see java.sql.Timestamp
0957: */
0958: public String convertTimestamp(final int type,
0959: final Timestamp timestamp) throws SQLException,
0960: TKIllegalConversionException {
0961: if (type == Types.TIMESTAMP) {
0962: return createTimestampLiteral(timestamp);
0963: }
0964:
0965: final TypeInfo type_info = (TypeInfo) db_types.get(new Integer(
0966: type));
0967: if (type_info == null)
0968: throw new TKIllegalConversionException(
0969: "java.sql.Timestamp", "JDBC-Type java.sql.Types."
0970: + TYPE_NAMES.get(new Integer(type)));
0971:
0972: if (supportsConvert(Types.TIMESTAMP, type)) {
0973: final String type_name = (String) TYPE_NAMES
0974: .get(new Integer(type));
0975:
0976: return "{fn CONVERT( " + createTimestampLiteral(timestamp)
0977: + ", " + type_name + ") }";
0978: } else {
0979: throw new TKIllegalConversionException(
0980: "java.sql.Timestamp", "java.sql."
0981: + TYPE_NAMES.get(new Integer(type)));
0982: }
0983: }
0984:
0985: public String toString() {
0986: final StringBuffer buf = new StringBuffer();
0987: String lineSep = System.getProperty("line.seperator");
0988:
0989: buf.append("{\t");
0990: final Enumeration types_enum = db_types.elements();
0991: while (types_enum.hasMoreElements()) {
0992: buf
0993: .append(((TypeInfo) types_enum.nextElement())
0994: .toString());
0995: if (types_enum.hasMoreElements())
0996: buf.append(",");
0997: buf.append(lineSep);
0998: buf.append("\t");
0999: }
1000: buf.append(lineSep);
1001: buf.append("}");
1002: return buf.toString();
1003: }
1004: //{{DECLARE_CONTROLS
1005: //}}
1006: }
|