KickJava   Java API By Example, From Geeks To Geeks.

Java > Open Source Codes > com > teamkonzept > db > TKSQLTypeConverter


1 /*
2  * $Header: /cvsroot/webman-cms/source/webman/com/teamkonzept/db/TKSQLTypeConverter.java,v 1.7 2002/01/25 12:06:01 ralf Exp $
3  *
4  */

5 package com.teamkonzept.db;
6
7 import java.io.*;
8 import java.math.*;
9 import java.sql.*;
10 import java.text.*;
11 import java.util.Enumeration JavaDoc;
12 import java.util.Hashtable JavaDoc;
13
14 public class TKSQLTypeConverter
15 {
16     public static PrintStream LOG = System.out;
17
18     public static final int HASHTABLE_SIZE = 19;
19
20     public static int HASH_CODE = TKSQLTypeConverter.class.getName().hashCode();
21     
22     final static Object JavaDoc[][] TYPE_NAMES_TABLE = {
23         { new Integer JavaDoc( Types.BIGINT ), "BIGINT" },
24         { new Integer JavaDoc( Types.BINARY ), "BINARY" },
25         { new Integer JavaDoc( Types.BIT ), "BIT" },
26         { new Integer JavaDoc( Types.CHAR ), "CHAR" },
27         { new Integer JavaDoc( Types.DATE ), "DATE" },
28         { new Integer JavaDoc( Types.DECIMAL ), "DECIMAL" },
29         { new Integer JavaDoc( Types.DOUBLE ), "DOUBLE" },
30         { new Integer JavaDoc( Types.FLOAT ), "FLOAT" },
31         { new Integer JavaDoc( Types.INTEGER ), "INTEGER" },
32         { new Integer JavaDoc( Types.LONGVARBINARY ), "LONGVARBINARY" },
33         { new Integer JavaDoc( Types.LONGVARCHAR ), "LONGVARCHAR" },
34         { new Integer JavaDoc( Types.NUMERIC ), "NUMERIC" },
35         { new Integer JavaDoc( Types.REAL ), "REAL" },
36         { new Integer JavaDoc( Types.SMALLINT ), "SMALLINT" },
37         { new Integer JavaDoc( Types.TIME ), "TIME" },
38         { new Integer JavaDoc( Types.TIMESTAMP ), "TIMESTAMP" },
39         { new Integer JavaDoc( Types.TINYINT ), "TINYINT" },
40         { new Integer JavaDoc( Types.VARBINARY ), "VARBINARY" },
41         { new Integer JavaDoc( Types.VARCHAR ), "VARCHAR" }
42     };
43     final static Hashtable JavaDoc TYPE_NAMES = initHash();
44             
45     static class TypeInfo {
46
47         int DATA_TYPE;
48             
49         String JavaDoc LITERAL_PREFIX;
50         String JavaDoc LITERAL_SUFFIX;
51         int PRECISION;
52         short MINIMUM_SCALE;
53         short MAXIMUM_SCALE;
54         boolean UNSIGNED_ATTRIBUTE;
55         int NUM_PREC_RADIX;
56
57         static int counter = 0;
58
59         TypeInfo( final ResultSet rs ) throws SQLException {
60             DATA_TYPE = rs.getInt( "DATA_TYPE" );
61             LITERAL_PREFIX = rs.getString( "LITERAL_PREFIX" );
62             LITERAL_SUFFIX = rs.getString( "LITERAL_SUFFIX" );
63             PRECISION = (int) rs.getLong( "PRECISION" );
64             MINIMUM_SCALE = rs.getShort( "MINIMUM_SCALE" );
65             MAXIMUM_SCALE = rs.getShort( "MAXIMUM_SCALE" );
66             UNSIGNED_ATTRIBUTE = rs.getBoolean( "UNSIGNED_ATTRIBUTE" );
67             NUM_PREC_RADIX = rs.getInt( "NUM_PREC_RADIX" );
68         }
69         TypeInfo( final int DATA_TYPE,
70                   final String JavaDoc LITERAL_PREFIX, final String JavaDoc LITERAL_SUFFIX,
71                   final int PRECISION,
72                   final int MINIMUM_SCALE, final int MAXIMUM_SCALE,
73                   final boolean UNSIGNED_ATTRIBUTE,
74                   final int NUM_PREC_RADIX )
75         {
76             this.DATA_TYPE = DATA_TYPE;
77             this.LITERAL_PREFIX = LITERAL_PREFIX;
78             this.LITERAL_SUFFIX = LITERAL_SUFFIX;
79             this.PRECISION = PRECISION;
80             this.MINIMUM_SCALE = (new Integer JavaDoc( MINIMUM_SCALE )).shortValue();
81             this.MAXIMUM_SCALE = (new Integer JavaDoc( MAXIMUM_SCALE )).shortValue();
82             this.UNSIGNED_ATTRIBUTE = UNSIGNED_ATTRIBUTE;
83             this.NUM_PREC_RADIX = NUM_PREC_RADIX;
84         
85         }
86         public boolean equals( final Object JavaDoc obj ) {
87             if (obj != null && getClass() == obj.getClass())
88             {
89                 return DATA_TYPE == ( (TypeInfo) obj ).DATA_TYPE;
90             }
91             return false;
92         }
93
94         public int hashCode()
95         {
96             return DATA_TYPE + HASH_CODE;
97         }
98         
99         public String JavaDoc toString() {
100             final String JavaDoc type_name = (String JavaDoc)TKSQLTypeConverter.TYPE_NAMES.get( new Integer JavaDoc( DATA_TYPE ) );
101             return "TypeInfo( " + DATA_TYPE + ( type_name != null ? " /* " + type_name + " */ " : "" ) + ",\t"
102                         + ( LITERAL_PREFIX != null ? "\"" + LITERAL_PREFIX + "\"" : "null" ) + ",\t"
103                         + ( LITERAL_SUFFIX != null ? "\"" + LITERAL_SUFFIX + "\"" : "null" ) + ",\t"
104                         + PRECISION + ",\t" + MINIMUM_SCALE + ",\t" + MAXIMUM_SCALE + ",\t"
105                         + UNSIGNED_ATTRIBUTE + ",\t" + NUM_PREC_RADIX + " )";
106         }
107     }
108     
109     protected final DatabaseMetaData meta_data;
110     protected final Hashtable JavaDoc db_types = new Hashtable JavaDoc( HASHTABLE_SIZE );
111
112     public TKSQLTypeConverter( final Connection conn ) throws SQLException
113     {
114         this.meta_data = conn.getMetaData();
115         
116         /*
117          * Lese die Beschreibung der von der DB unterst¸tzten
118          * Datentypen aus.
119          */

120         final ResultSet type_rs = meta_data.getTypeInfo();
121         while ( type_rs.next() ) {
122         
123             final TypeInfo db_type = new TypeInfo( type_rs );
124             final Integer JavaDoc data_type = new Integer JavaDoc( db_type.DATA_TYPE );
125             if ( ! db_types.containsKey( data_type ) )
126                 db_types.put( data_type, db_type );
127         }
128         type_rs.close();
129     }
130     protected TKSQLTypeConverter( final TypeInfo[] meta_data )
131     {
132         for ( int i = 0; i < meta_data.length; i++ ) {
133             final Integer JavaDoc data_type = new Integer JavaDoc( meta_data[i].DATA_TYPE );
134             if ( ! db_types.containsKey( data_type ) )
135                 db_types.put( data_type, meta_data[i] );
136         }
137         this.meta_data = null;
138     }
139     /** liest den Array TYPE_NAMES_TABLE ein und erstellt daraus
140      * eine Hashtable.
141      *
142      * @return TYPE_NAMES_TABLE als Hashtable
143      */

144     private static Hashtable JavaDoc initHash()
145     {
146         final Hashtable JavaDoc table = new Hashtable JavaDoc( TYPE_NAMES_TABLE.length );
147         
148         for ( int i = 0; i < TYPE_NAMES_TABLE.length; i++ ) {
149             table.put( TYPE_NAMES_TABLE[i][0], TYPE_NAMES_TABLE[i][1] );
150         }
151         
152         return table;
153     }
154
155     /** &Uuml;berpr&uuml;fe, ob das DBMS die angegebene Konvertierung
156      * mittels der CONVERT() Funktion erlaubt.
157      *
158      * @param int from_type JDBC-Quelltyp
159      * @param int to_type JDBC-Zieltyp
160      * @return true, falls die Konvertierung zul&auml;ssig ist; false sonst
161      */

162     public boolean supportsConvert( final int from_type, final int to_type )
163                                                         throws SQLException
164     {
165         return meta_data.supportsConvert( from_type, to_type );
166     }
167     /** Versehe alle LITERAL_PREFIX u. -SUFFIX Strings mit
168      * einem Escape-Zeichen (verdoppeln)
169      *
170      * @param String str der Eingabe-String, in dem alle Vorkomnisse
171      * LITERAL_PREFIX u. -SUFFIX "gesch&uuml;tzt" werden soll.
172      * @param TypeInfo info DBMS-Typeninfo
173      * @return <str> mit verdoppeltem LITERAL_PREFIX u. -SUFFIX'en
174      */

175     protected static String JavaDoc escapeQuotes( final String JavaDoc str,
176                                           final TypeInfo info )
177     {
178     
179         if ( info.LITERAL_PREFIX != null ) {
180             final String JavaDoc buf = doubleQuotes( str, info.LITERAL_PREFIX );
181             
182             if ( info.LITERAL_SUFFIX != null &&
183                  ! info.LITERAL_PREFIX.equals( info.LITERAL_SUFFIX ) ) {
184                 return doubleQuotes( buf, info.LITERAL_SUFFIX );
185             } else {
186                 return buf;
187             }
188         } else if ( info.LITERAL_SUFFIX != null ) {
189             return doubleQuotes( str, info.LITERAL_SUFFIX );
190         } else {
191             return str;
192         }
193     }
194     /** Verdoppele alle Vorkommnisse des Strings <quote> im Eingabestring
195      *
196      * @param String literal der String, in dem alle Vorkomnisse
197      * von <quote>-Strings verdoppelt werden soll
198      * @param String quote die zu verdoppelnde Zeichenkette
199      * @return <literal> mit verdoppeltem <qoute>'s
200      */

201     protected static String JavaDoc doubleQuotes( final String JavaDoc literal,
202                                           final String JavaDoc quote )
203     {
204         final StringBuffer JavaDoc buf = new StringBuffer JavaDoc();
205         
206         int start = 0;
207         int end;
208         while ( ( end = literal.indexOf( quote, start ) ) > 0 ) {
209             buf.append( literal.substring( start, end ) + quote + quote );
210             start = end + 1;
211         }
212         buf.append( literal.substring( start, literal.length() ) );
213
214         return buf.toString();
215     }
216     /** Erzeuge ein Stringliteral, d.h. fasse den String in
217      * LITERAL_PREFIX u. -_SUFFIX ein.
218      *
219      * @param TypeInfo info Typenbeshreibung
220      * @param String str der zu konvertierenden String
221      * @return SQL-Stringliteral
222      */

223     protected static String JavaDoc createStringLiteral( final TypeInfo info, final String JavaDoc str )
224     {
225         final StringBuffer JavaDoc result = new StringBuffer JavaDoc();
226                 
227         if ( info.LITERAL_PREFIX != null )
228             result.append( info.LITERAL_PREFIX );
229     
230         result.append( escapeQuotes( str, info ) );
231             
232         if ( info.LITERAL_SUFFIX != null )
233             result.append( info.LITERAL_SUFFIX );
234                 
235         return result.toString();
236     }
237
238     /** Erzeugt eine NumberFormat-Klasse f&uuml;r den angegeben JDBC-Typen.
239      * Je nach Typen, wird Prefix, Suffix und Genauigkeit der
240      * NumberFormat-Klasse gesetzt.
241      *
242      * @param int type JDBC-Zieltyp (java.sql.Types)
243      * @return die entsprechende NumberFormat-Klasse
244      *
245      * @see java.text.NumberFormat
246      * @see java.text.DecimalFormat
247      */

248     protected static NumberFormat getNumberFormat( final TypeInfo info )
249     {
250         // Format-Symbole setzen
251
final DecimalFormatSymbols symbols = new DecimalFormatSymbols();
252         symbols.setMinusSign( '-' );
253         symbols.setDecimalSeparator( '.' );
254         symbols.setZeroDigit( '0' );
255         
256         // Zahlen-Muster setzen
257
final StringBuffer JavaDoc pattern = new StringBuffer JavaDoc();
258         if ( info.LITERAL_PREFIX != null )
259             pattern.append( info.LITERAL_PREFIX );
260         pattern.append( "#.#" );
261         if ( info.LITERAL_SUFFIX != null )
262             pattern.append( info.LITERAL_SUFFIX );
263             
264         // Formatklasse erzeugen
265
final DecimalFormat format = new DecimalFormat( pattern.toString(), symbols );
266         format.setMinimumFractionDigits( info.MINIMUM_SCALE );
267         format.setMaximumFractionDigits( info.MAXIMUM_SCALE );
268         format.setMinimumIntegerDigits( 0 );
269         format.setMaximumIntegerDigits( info.PRECISION - info.MINIMUM_SCALE );
270         format.setGroupingUsed( false );
271
272         
273         return format;
274     }
275     /** Versucht eine geeignete Konvertierung f&uuml;r die gegebene
276      * Zahl <num> zu finden. Es wird erst nach einer vom DBMS
277      * unterst&uuml;tzten Konvertierung gesucht, wobei der Reihe nach
278      * jeweils eine Konvertierung der Form
279      * <num> -> <from_types[0]> -> to_type, ..., <num> -> <from_types[n]> -> to_type
280      * gesucht wird. Erst danach wird <num> in <from_types[0]> konvertiert
281      * und von da aus in <to_type>.
282      *
283      * @param int[] from_types Liste von m&ouml;glichen JDBC-Typen, in die
284      * <num> umgewandelt werden kann, um von da aus in
285      * <to_type> konvertiert zu werden.
286      * @param int to_type JDBC-Zieltyp
287      * @param Number num die zu konvertierende Zahl
288      * @return SQL-Textrepr&auml;sentation der in den JDBC-Typ
289      * umgewandelten Zahl. Dies kann gegebenfalls
290      * auch ein String der Form "CONVERT( type, value )" sein.
291      *
292      * @see java.sql.DatabaseMetaData#supportsConvert
293      * @see java.sql.Types
294      */

295     protected String JavaDoc standardNumberConversion( final int[] from_types,
296                                                final int to_type,
297                                                final Number JavaDoc num )
298                                                         throws SQLException,
299                                                                TKIllegalConversionException
300     {
301         for ( int i = 0; i < from_types.length; i++ ) {
302             if ( supportsConvert( from_types[i], to_type ) ) {
303                 final TypeInfo info = (TypeInfo) db_types.get( new Integer JavaDoc( from_types[i] ) );
304                 final String JavaDoc type_name = (String JavaDoc) TYPE_NAMES.get( new Integer JavaDoc( to_type ) );
305                 final String JavaDoc literal = createNumberLiteral( info, num );;
306                     
307                 return "{fn CONVERT(" + literal + ", " + type_name + ") }";
308             }
309         }
310             
311         final TypeInfo info = (TypeInfo) db_types.get( new Integer JavaDoc( from_types[0] ) );
312             
313         switch ( to_type ) {
314     
315         case Types.CHAR:
316         case Types.VARCHAR:
317         case Types.LONGVARCHAR:
318             return createStringLiteral( info, createNumberLiteral( info, num ) );
319                 
320         case Types.BIT:
321             final boolean state;
322
323             if ( num instanceof BigDecimal ||
324                  num instanceof Float JavaDoc ||
325                  num instanceof Double JavaDoc )
326                 state = num.doubleValue() != 0 ? true : false;
327             else
328                 state = num.longValue() != 0 ? true : false;
329                 
330             return createBitLiteral( info, state );
331             
332         default:
333             throw new TKIllegalConversionException( num.getClass().getName(),
334                                                     "java.sql." + TYPE_NAMES.get( new Integer JavaDoc( to_type ) ) );
335         }
336     }
337     /** Erzeuge ein Zahlen-Literal, d.h. fasse die
338      * SQL-Textrepr&auml;sentation der Zahl in
339      * LITERAL_PREFIX u. -_SUFFIX ein
340      *
341      * @param TypeInfo info DBMS-Typenbeshreibung
342      * @param Number num Die umzuwandelnde Zahl
343      * @return SQL-Textrepr&auml;sentation
344      */

345     protected static String JavaDoc createNumberLiteral( final TypeInfo info, final Number JavaDoc num )
346     {
347         switch ( info.DATA_TYPE ) {
348         
349         case Types.NUMERIC:
350         case Types.DECIMAL:
351             if ( num instanceof BigDecimal ) {
352                 BigDecimal dec = (BigDecimal) num;
353                 final int scale = dec.scale();
354                 
355                 if ( scale < info.MINIMUM_SCALE )
356                     dec = dec.setScale( info.MINIMUM_SCALE );
357                 else if ( scale > info.MAXIMUM_SCALE )
358                     dec = dec.setScale( info.MAXIMUM_SCALE, BigDecimal.ROUND_HALF_DOWN );
359                 
360                 final StringBuffer JavaDoc literal = new StringBuffer JavaDoc();
361                 if ( info.LITERAL_PREFIX != null )
362                     literal.append( info.LITERAL_PREFIX );
363                 literal.append( dec.toString() );
364                 if ( info.LITERAL_SUFFIX != null )
365                     literal.append( info.LITERAL_SUFFIX );
366                 return literal.toString();
367             }
368             
369         case Types.FLOAT:
370         case Types.DOUBLE:
371         case Types.REAL:
372             return getNumberFormat( info ).format( num.doubleValue() );
373             
374         default:
375             return getNumberFormat( info ).format( num.longValue() );
376         }
377     }
378     /** Erzeuge ein Bitliteral, d.h. fasse die
379      * SQL-Textrepr&auml;sentation des Bool'schen-Wertes (=0|1) in
380      * LITERAL_PREFIX u. -_SUFFIX ein.
381      *
382      * @param TypeInfo info DBMS-Typenbeshreibung
383      * @param boolean state Der umzuwandelnde Bool'sche Wert
384      * @return SQL-Textrepr&auml;sentation
385      */

386     protected static String JavaDoc createBitLiteral( final TypeInfo info, final boolean state )
387     {
388         final StringBuffer JavaDoc literal = new StringBuffer JavaDoc();
389         
390         if ( info.LITERAL_PREFIX != null )
391             literal.append( info.LITERAL_PREFIX );
392             
393         literal.append( state ? "1" : "0" );
394                     
395         if ( info.LITERAL_SUFFIX != null )
396             literal.append( info.LITERAL_SUFFIX );
397             
398         return literal.toString();
399     }
400     /** Erzeuge ein Bytestringliteral, d.h. fasse die
401      * SQL-Textrepr&auml;sentation (Hexadezimaldarst.) des Byte-Arrays in
402      * LITERAL_PREFIX u. -_SUFFIX ein.
403      *
404      * @param TypeInfo info DBMS-Typenbeshreibung
405      * @param Byte[] data Der umzuwandelnde Byte-Array
406      * @return SQL-Textrepr&auml;sentation
407      */

408     protected static String JavaDoc createBytestringLiteral( final TypeInfo info, final Byte JavaDoc[] data )
409     {
410         final StringBuffer JavaDoc literal = new StringBuffer JavaDoc();
411         
412         if ( info.LITERAL_PREFIX != null )
413             literal.append( info.LITERAL_PREFIX );
414             
415         
416         for ( int i = 0; i < data.length; i++ )
417             literal.append( Integer.toHexString( data[i].intValue() ) );
418                     
419         if ( info.LITERAL_SUFFIX != null )
420             literal.append( info.LITERAL_SUFFIX );
421             
422         return literal.toString();
423     }
424     /** Erzeuge ein Datumsliteral, d.h. schreibe das Datum, als
425      * SQL Escape Statement
426      *
427      * @param Date date das umzuwandelnde Datum
428      * @return SQL-Textrepr&auml;sentation
429      */

430     protected static String JavaDoc createDateLiteral( final java.sql.Date JavaDoc date )
431     {
432         return "{d '" + date.toString() + "'}";
433     }
434     /** Erzeuge ein Timeliteral, d.h. schreibe die Zeit, als
435      * SQL Escape Statement
436      *
437      * @param Time time das umzuwandelnde Zeitobjekt
438      * @return SQL-Textrepr&auml;sentation
439      */

440     protected static String JavaDoc createTimeLiteral( final Time time )
441     {
442         return "{t '" + time.toString() + "'}";
443     }
444     /** Erzeuge ein Timestampliteral, d.h. schreibe den Zeitstempel, als
445      * SQL Escape Statement
446      *
447      * @param Timestamp timestamp das umzuwandelnde Zeitstempelobjekt
448      * @return SQL-Textrepr&auml;sentation
449      */

450     protected static String JavaDoc createTimestampLiteral( final Timestamp timestamp )
451     {
452         return "{ts '" + timestamp.toString() + "'}";
453     }
454     /** "Frontend"-Methode zu den restlichen convertXXX()-Methoden.
455      * Liefert die SQL-Textrepr&auml;sentation des Objektes
456      * im gew&uuml;schten Typ.
457      *
458      * @param int type JDBC-Zieltyp
459      * @param Object obj das zu konvertierende Objekt
460      *
461      * @return SQL-Textrepr&auml;sentation des in den JDBC-Typ
462      * umgewandelten Objektes. Dies kann gegebenfalls
463      * auch ein String der Form "CONVERT( type, value )" sein.
464      *
465      * @see java.sql.Types
466      */

467     public String JavaDoc convert( final int type, final Object JavaDoc obj )
468                                                         throws SQLException,
469                                                                TKIllegalConversionException
470     {
471         if ( obj instanceof String JavaDoc )
472             return convertString( type, (String JavaDoc)obj );
473         
474         if ( obj instanceof BigDecimal )
475             return convertBigDecimal( type, (BigDecimal)obj );
476         
477         if ( obj instanceof Boolean JavaDoc )
478             return convertBoolean( type, (Boolean JavaDoc)obj );
479             
480         if ( obj instanceof Byte JavaDoc )
481             return convertByte( type, (Byte JavaDoc)obj );
482             
483         if ( obj instanceof Short JavaDoc )
484             return convertShort( type, (Short JavaDoc)obj );
485         
486         if ( obj instanceof Integer JavaDoc )
487             return convertInteger( type, (Integer JavaDoc)obj );
488             
489         if ( obj instanceof Long JavaDoc )
490             return convertLong( type, (Long JavaDoc)obj );
491             
492         if ( obj instanceof Float JavaDoc )
493             return convertFloat( type, (Float JavaDoc)obj );
494
495         if ( obj instanceof Double JavaDoc )
496             return convertDouble( type, (Double JavaDoc)obj );
497             
498         if ( obj instanceof Byte JavaDoc[] )
499             return convertByteArray( type, (Byte JavaDoc[])obj );
500
501         if ( obj instanceof java.sql.Date JavaDoc )
502             return convertDate( type, (java.sql.Date JavaDoc)obj );
503                         
504         if ( obj instanceof Time )
505             return convertTime( type, (Time)obj );
506             
507         if ( obj instanceof Timestamp )
508             return convertTimestamp( type, (Timestamp)obj );
509             
510         throw new TKIllegalConversionException( obj.getClass().getName(),
511                                                 "java.sql." + TYPE_NAMES.get( new Integer JavaDoc( type ) ) );
512     }
513     /** "Generische" Methode zur Konvertierung von Zahlen-Objekten.
514      * Erzeugt ein Zahlenliteral, falls nur in ein anderen Zahlentyp
515      * konvertiert werden soll, ansonsten wird auf die Methode
516      * standardNumberConversion() zur&uuml;ckgegriffen.
517      *
518      * @param int[] from_types Liste von m&ouml;glichen JDBC-Typen, in die
519      * <num> umgewandelt werden kann, um von da aus in
520      * <to_type> konvertiert zu werden.
521      * @param int to_type JDBC-Zieltyp
522      *
523      * @return SQL-Textrepr&auml;sentation der in den JDBC-Typ
524      * umgewandelten Zahl. Dies kann gegebenfalls
525      * auch ein String der Form "CONVERT( type, value )" sein.
526      *
527      * @see com.teamkonzept.db.TKSQLTypeConverter.standardNumberConversion
528      * @see java.sql.Types
529      */

530     protected String JavaDoc convertNumber( final int[] from_types,
531                                     final int to_type,
532                                     final Number JavaDoc num )
533                                                         throws SQLException,
534                                                                TKIllegalConversionException
535     {
536         final TypeInfo type_info = (TypeInfo) db_types.get( new Integer JavaDoc( to_type ) );
537         if ( type_info == null )
538             throw new TKIllegalConversionException(
539                 num.getClass().getName(),
540                 "JDBC-Type java.sql.Types." + TYPE_NAMES.get( new Integer JavaDoc( to_type ) )
541             );
542
543         switch ( to_type ) {
544         
545         case Types.NUMERIC:
546         case Types.DECIMAL:
547         case Types.DOUBLE:
548         case Types.FLOAT:
549         case Types.REAL:
550         case Types.INTEGER:
551         case Types.BIGINT:
552         case Types.SMALLINT:
553         case Types.TINYINT:
554             return createNumberLiteral( type_info, num );
555                         
556         default:
557             /* Versuche, ob eine Konvertierung mittels der
558              * DBMS-CONVERT-Funktion mˆglich ist, ansonsten
559              * verwende, soweit mˆglich, eine eigene Konvertierung,
560              * oder werfe eine Exception
561              */

562             return standardNumberConversion( from_types, to_type, num );
563         }
564     }
565     /** Konvertiert ein String Objekt in den angegeben JDBC-Typ und
566      * liefert dessen SQL-Textrepr&auml;sentation.
567      *
568      * @param int type JDBC-Zieltyp (java.sql.Types)
569      * @param String str der zu konvertierenden String
570      * @return SQL-Textrepr&auml;sentation des in den JDBC-Typ
571      * umgewandelten Eingabestrings. Dies kann gegebenfalls
572      * auch ein String der Form "CONVERT( type, value )" sein.
573      *
574      * @see java.sql.DatabaseMetaData#supportsConvert
575      * @see java.sql.Types
576      */

577     public String JavaDoc convertString( final int type, final String JavaDoc str )
578                                                         throws SQLException,
579                                                                TKIllegalConversionException
580     {
581         final TypeInfo type_info = (TypeInfo) db_types.get( new Integer JavaDoc( type ) );
582         if ( type_info == null )
583             throw new TKIllegalConversionException(
584                 "java.lang.String",
585                 "JDBC-Type java.sql.Types." + TYPE_NAMES.get( new Integer JavaDoc( type ) )
586             );
587             
588         switch ( type ) {
589         
590         case Types.CHAR:
591         case Types.VARCHAR:
592         case Types.LONGVARCHAR:
593             return createStringLiteral( type_info , str );
594         
595         default:
596             
597             /* Versuche, ob eine Konvertierung mittels der
598              * DBMS-CONVERT-Funktion mˆglich ist, ansonsten
599              * gib den String, so wie er ist zur¸ck
600              */

601             final int[] from_types = { Types.CHAR,
602                                        Types.VARCHAR,
603                                        Types.LONGVARCHAR
604                                      };
605             for ( int i = 0; i < from_types.length; i++ ) {
606                 if ( supportsConvert( from_types[i], type ) ) {
607                     final TypeInfo info = (TypeInfo) db_types.get( new Integer JavaDoc( from_types[i] ) );
608                     final String JavaDoc literal = createStringLiteral( info, str );
609                     final String JavaDoc type_name = (String JavaDoc) TYPE_NAMES.get( new Integer JavaDoc( type ) );
610                     
611                     return "{fn CONVERT( " + literal + ", " + type_name + ") }";
612                 }
613             }
614             
615             return str;
616         }
617     }
618     /** Konvertiert ein Bool'schen Wert in den angegeben JDBC-Typ und
619      * liefert dessen SQL-Textrepr&auml;sentation.
620      *
621      * @param int type JDBC-Zieltyp (java.sql.Types)
622      * @param BigDecimal num die zu konvertierenden Bool'sche Wert
623      * @return SQL-Textrepr&auml;sentation des in den JDBC-Typ
624      * umgewandelten Bool'sche Wert. Dies kann gegebenfalls
625      * auch ein String der Form "CONVERT( type, value )" sein.
626      *
627      * @see java.sql.DatabaseMetaData#supportsConvert
628      * @see java.sql.Types
629      */

630     public String JavaDoc convertBoolean( final int type, final Boolean JavaDoc state )
631                                                         throws SQLException,
632                                                                TKIllegalConversionException
633     {
634         final TypeInfo type_info = (TypeInfo) db_types.get( new Integer JavaDoc( type ) );
635         if ( type_info == null )
636             throw new TKIllegalConversionException(
637                 "java.lang.Boolean",
638                 "JDBC-Type java.sql.Types." + TYPE_NAMES.get( new Integer JavaDoc( type ) )
639             );
640                         
641         switch ( type ) {
642         
643         case Types.BIT:
644             return createBitLiteral( type_info, state.booleanValue() );
645             
646         default:
647             if ( supportsConvert( Types.BIT, type ) ) {
648                 final String JavaDoc type_name = (String JavaDoc) TYPE_NAMES.get( new Integer JavaDoc( type ) );
649                     
650                 return "{fn CONVERT( " + createBitLiteral( type_info, state.booleanValue() )
651                             + ", " + type_name + ") }";
652             } else {
653                 throw new TKIllegalConversionException( "java.lang.Boolean",
654                                                         "JDBC-Type java.sql.Types." + TYPE_NAMES.get( new Integer JavaDoc( type ) ) );
655             }
656         }
657     }
658     /** Konvertiert ein byte in den angegeben JDBC-Typ und
659      * liefert dessen SQL-Textrepr&auml;sentation.
660      *
661      * @param int type JDBC-Zieltyp (java.sql.Types)
662      * @param Byte num der zu konvertierenden Byte Wert
663      * @return SQL-Textrepr&auml;sentation des in den JDBC-Typen
664      * umgewandelten Byte-Wertes. Dies kann gegebenfalls
665      * auch ein String der Form "CONVERT( type, value )" sein.
666      *
667      * @see java.sql.DatabaseMetaData#supportsConvert
668      * @see java.sql.Types
669      */

670     public String JavaDoc convertByte( final int type, final Byte JavaDoc num )
671                                                         throws SQLException,
672                                                                TKIllegalConversionException
673     {
674         final int[] from_types = { Types.TINYINT, Types.SMALLINT, Types.INTEGER,
675                                    Types.BIGINT, Types.FLOAT, Types.DOUBLE,
676                                    Types.REAL, Types.NUMERIC, Types.DECIMAL
677                                  };
678         return convertNumber( from_types, type, num );
679     }
680     /** Konvertiert ein Bytearray in den angegeben JDBC-Typ und
681      * liefert dessen SQL-Textrepr&auml;sentation.
682      *
683      * @param int type JDBC-Zieltyp (java.sql.Types)
684      * @param Byte[] data der zu konvertierenden Byte Wert
685      * @return SQL-Textrepr&auml;sentation des in den JDBC-Typen
686      * umgewandelten Byte-Feldes. Dies kann gegebenfalls
687      * auch ein String der Form "CONVERT( type, value )" sein.
688      *
689      * @see java.sql.DatabaseMetaData#supportsConvert
690      * @see java.sql.Types
691      */

692     public String JavaDoc convertByteArray( final int type, final Byte JavaDoc[] data )
693                                                         throws SQLException,
694                                                                TKIllegalConversionException
695     {
696         final TypeInfo type_info = (TypeInfo) db_types.get( new Integer JavaDoc( type ) );
697         if ( type_info == null )
698             throw new TKIllegalConversionException(
699                 "java.lang.Byte[]",
700                 "JDBC-Type java.sql.Types." + TYPE_NAMES.get( new Integer JavaDoc( type ) )
701             );
702                         
703         switch ( type ) {
704         
705         case Types.BINARY:
706         case Types.VARBINARY:
707         case Types.LONGVARBINARY:
708             return createBytestringLiteral( type_info, data );
709             
710         default:
711
712             final int[] from_types = { Types.BINARY, Types.VARBINARY, Types.LONGVARBINARY };
713             
714             for ( int i = 0; i < from_types.length; i++ ) {
715                 if ( supportsConvert( from_types[i], type ) ) {
716                     final TypeInfo info = (TypeInfo) db_types.get( new Integer JavaDoc( from_types[i] ) );
717                     final String JavaDoc type_name = (String JavaDoc) TYPE_NAMES.get( new Integer JavaDoc( type ) );
718                     final String JavaDoc literal = createBytestringLiteral( info, data );
719                         
720                     return "{fn CONVERT( " + literal + ", " + type_name + ") }";
721                 }
722             }
723             throw new TKIllegalConversionException( "java.lang.Byte[]",
724                                                     "JDBC-Type java.sql.Types." + TYPE_NAMES.get( new Integer JavaDoc( type ) ) );
725         }
726     }
727     /** Konvertiert ein Short-Wert in den angegeben JDBC-Typ und
728      * liefert dessen SQL-Textrepr&auml;sentation.
729      *
730      * @param int type JDBC-Zieltyp (java.sql.Types)
731      * @param Short num der zu konvertierenden Short-Wert
732      * @return SQL-Textrepr&auml;sentation des in den JDBC-Typen
733      * umgewandelten Short-Wertes. Dies kann gegebenfalls
734      * auch ein String der Form "CONVERT( type, value )" sein.
735      *
736      * @see java.sql.DatabaseMetaData#supportsConvert
737      * @see java.sql.Types
738      */

739     public String JavaDoc convertShort( final int type, final Short JavaDoc num )
740                                                         throws SQLException,
741                                                                TKIllegalConversionException
742     {
743         final int[] from_types = { Types.SMALLINT, Types.INTEGER, Types.BIGINT,
744                                    Types.FLOAT, Types.DOUBLE, Types.REAL,
745                                    Types.NUMERIC, Types.DECIMAL
746                                  };
747         return convertNumber( from_types, type, num );
748     }
749     /** Konvertiert ein Integer-Wert in den angegeben JDBC-Typ und
750      * liefert dessen SQL-Textrepr&auml;sentation.
751      *
752      * @param int type JDBC-Zieltyp (java.sql.Types)
753      * @param Integer num der zu konvertierenden Integer-Wert
754      * @return SQL-Textrepr&auml;sentation des in den JDBC-Typen
755      * umgewandelten Integer-Wertes. Dies kann gegebenfalls
756      * auch ein String der Form "CONVERT( type, value )" sein.
757      *
758      * @see java.sql.DatabaseMetaData#supportsConvert
759      * @see java.sql.Types
760      */

761     public String JavaDoc convertInteger( final int type, final Integer JavaDoc num )
762                                                         throws SQLException,
763                                                                TKIllegalConversionException
764     {
765         final int[] from_types = { Types.INTEGER, Types.BIGINT,
766                                    Types.FLOAT, Types.DOUBLE, Types.REAL,
767                                    Types.NUMERIC, Types.DECIMAL
768                                  };
769         return convertNumber( from_types, type, num );
770     }
771     /** Konvertiert ein Long-Wert in den angegeben JDBC-Typ und
772      * liefert dessen SQL-Textrepr&auml;sentation.
773      *
774      * @param int type JDBC-Zieltyp (java.sql.Types)
775      * @param Long num der zu konvertierenden Float-Wert
776      * @return SQL-Textrepr&auml;sentation des in den JDBC-Typen
777      * umgewandelten Long-Wertes. Dies kann gegebenfalls
778      * auch ein String der Form "CONVERT( type, value )" sein.
779      *
780      * @see java.sql.DatabaseMetaData#supportsConvert
781      * @see java.sql.Types
782      */

783     public String JavaDoc convertLong( final int type, final Long JavaDoc num )
784                                                         throws SQLException,
785                                                                TKIllegalConversionException
786     {
787         final int[] from_types = { Types.BIGINT,
788                                    Types.FLOAT, Types.DOUBLE, Types.REAL,
789                                    Types.NUMERIC, Types.DECIMAL
790                                  };
791         return convertNumber( from_types, type, num );
792     }
793     /** Konvertiert ein Float-Wert in den angegeben JDBC-Typ und
794      * liefert dessen SQL-Textrepr&auml;sentation.
795      *
796      * @param int type JDBC-Zieltyp (java.sql.Types)
797      * @param Float num der zu konvertierenden Float-Wert
798      * @return SQL-Textrepr&auml;sentation des in den JDBC-Typen
799      * umgewandelten Float-Wertes. Dies kann gegebenfalls
800      * auch ein String der Form "CONVERT( type, value )" sein.
801      *
802      * @see java.sql.DatabaseMetaData#supportsConvert
803      * @see java.sql.Types
804      */

805     public String JavaDoc convertFloat( final int type, final Float JavaDoc num )
806                                                         throws SQLException,
807                                                                TKIllegalConversionException
808     {
809         final int[] from_types = { Types.FLOAT, Types.DOUBLE, Types.REAL,
810                                    Types.NUMERIC, Types.DECIMAL
811                                  };
812         return convertNumber( from_types, type, num );
813     }
814     /** Konvertiert ein Double-Wert in den angegeben JDBC-Typ und
815      * liefert dessen SQL-Textrepr&auml;sentation.
816      *
817      * @param int type JDBC-Zieltyp (java.sql.Types)
818      * @param Double num der zu konvertierenden Double-Wert
819      * @return SQL-Textrepr&auml;sentation des in den JDBC-Typen
820      * umgewandelten Double-Wertes. Dies kann gegebenfalls
821      * auch ein String der Form "CONVERT( type, value )" sein.
822      *
823      * @see java.sql.DatabaseMetaData#supportsConvert
824      * @see java.sql.Types
825      */

826     public String JavaDoc convertDouble( final int type, final Double JavaDoc num )
827                                                         throws SQLException,
828                                                                TKIllegalConversionException
829     {
830         final int[] from_types = { Types.DOUBLE, Types.REAL,
831                                    Types.NUMERIC, Types.DECIMAL
832                                  };
833         return convertNumber( from_types, type, num );
834     }
835     /** Konvertiert ein BigDecimal Objekt in den angegeben JDBC-Typ und
836      * liefert dessen SQL-Textrepr&auml;sentation.
837      *
838      * @param int type JDBC-Zieltyp (java.sql.Types)
839      * @param BigDecimal num die zu konvertierenden BigDecimal-Zahl
840      * @return SQL-Textrepr&auml;sentation der in den JDBC-Typ
841      * umgewandelten BigDecimal-Zahl. Dies kann gegebenfalls
842      * auch ein String der Form "CONVERT( type, value )" sein.
843      *
844      * @see java.sql.DatabaseMetaData#supportsConvert
845      * @see java.sql.Types
846      * @see java.math.BigDecimal
847      */

848     public String JavaDoc convertBigDecimal( final int type, final BigDecimal num )
849                                                         throws SQLException,
850                                                                TKIllegalConversionException
851     {
852         final int[] from_types = { Types.NUMERIC, Types.DECIMAL };
853
854         return convertNumber( from_types, type, num );
855     }
856     /** Konvertiert ein java.sql.Date Objekt in den angegeben JDBC-Typ und
857      * liefert dessen SQL-Textrepr&auml;sentation.
858      *
859      * @param int type JDBC-Zieltyp (java.sql.Types)
860      * @param Date date das zu konvertierenden Datumsobjekt
861      * @return SQL-Textrepr&auml;sentation des in den JDBC-Typ
862      * umgewandelten Datums. Dies kann gegebenfalls
863      * auch ein String der Form "CONVERT( type, value )" sein.
864      *
865      * @see java.sql.DatabaseMetaData#supportsConvert
866      * @see java.sql.Types
867      * @see java.sql.Date
868      */

869     public String JavaDoc convertDate( final int type, final java.sql.Date JavaDoc date )
870                                                         throws SQLException,
871                                                                TKIllegalConversionException
872     {
873         if ( type == Types.DATE ) {
874             return createDateLiteral( date );
875         }
876         
877         final TypeInfo type_info = (TypeInfo) db_types.get( new Integer JavaDoc( type ) );
878         if ( type_info == null )
879             throw new TKIllegalConversionException(
880                 "java.sql.Date",
881                 "JDBC-Type java.sql.Types." + TYPE_NAMES.get( new Integer JavaDoc( type ) )
882             );
883
884         if ( supportsConvert( Types.DATE, type ) ) {
885             final String JavaDoc type_name = (String JavaDoc) TYPE_NAMES.get( new Integer JavaDoc( type ) );
886                     
887             return "{fn CONVERT( " + createDateLiteral( date ) + ", " + type_name + ") }";
888         } else {
889             throw new TKIllegalConversionException( "java.sql.Date",
890                                                     "JDBC-Type java.sql.Types." + TYPE_NAMES.get( new Integer JavaDoc( type ) ) );
891         }
892     }
893     /** Konvertiert ein java.sql.Time Objekt in den angegeben JDBC-Typ und
894      * liefert dessen SQL-Textrepr&auml;sentation.
895      *
896      * @param int type JDBC-Zieltyp (java.sql.Types)
897      * @param Time time das zu konvertierenden Zeitobjekt
898      * @return SQL-Textrepr&auml;sentation der in den JDBC-Typ
899      * umgewandelten Zeit. Dies kann gegebenfalls
900      * auch ein String der Form "CONVERT( type, value )" sein.
901      *
902      * @see java.sql.DatabaseMetaData#supportsConvert
903      * @see java.sql.Types
904      * @see java.sql.Time
905      */

906     public String JavaDoc convertTime( final int type, final Time time )
907                                                         throws SQLException,
908                                                                TKIllegalConversionException
909     {
910         if ( type == Types.TIME ) {
911             return createTimeLiteral( time );
912         }
913                         
914         final TypeInfo type_info = (TypeInfo) db_types.get( new Integer JavaDoc( type ) );
915         if ( type_info == null )
916             throw new TKIllegalConversionException(
917                 "java.sql.Time",
918                 "JDBC-Type java.sql.Types." + TYPE_NAMES.get( new Integer JavaDoc( type ) )
919             );
920                 
921         if ( supportsConvert( Types.TIME, type ) ) {
922             final String JavaDoc type_name = (String JavaDoc) TYPE_NAMES.get( new Integer JavaDoc( type ) );
923                     
924             return "{fn CONVERT( " + createTimeLiteral( time ) + ", " + type_name + ") }";
925         } else {
926             throw new TKIllegalConversionException( "java.sql.Time",
927                                                     "java.sql." + TYPE_NAMES.get( new Integer JavaDoc( type ) ) );
928         }
929     }
930     /** Konvertiert ein java.sql.Timestamp Objekt in den angegeben JDBC-Typ und
931      * liefert dessen SQL-Textrepr&auml;sentation.
932      *
933      * @param int type JDBC-Zieltyp (java.sql.Types)
934      * @param Timestamp timestamp das zu konvertierenden Zeitstempelobjekt
935      * @return SQL-Textrepr&auml;sentation der in den JDBC-Typ
936      * umgewandelten Zeit. Dies kann gegebenfalls
937      * auch ein String der Form "CONVERT( type, value )" sein.
938      *
939      * @see java.sql.DatabaseMetaData#supportsConvert
940      * @see java.sql.Types
941      * @see java.sql.Timestamp
942      */

943     public String JavaDoc convertTimestamp( final int type, final Timestamp timestamp )
944                                                         throws SQLException,
945                                                                TKIllegalConversionException
946     {
947         if ( type == Types.TIMESTAMP ) {
948             return createTimestampLiteral( timestamp );
949         }
950             
951         final TypeInfo type_info = (TypeInfo) db_types.get( new Integer JavaDoc( type ) );
952         if ( type_info == null )
953             throw new TKIllegalConversionException(
954                 "java.sql.Timestamp",
955                 "JDBC-Type java.sql.Types." + TYPE_NAMES.get( new Integer JavaDoc( type ) )
956             );
957                 
958         if ( supportsConvert( Types.TIMESTAMP, type ) ) {
959             final String JavaDoc type_name = (String JavaDoc) TYPE_NAMES.get( new Integer JavaDoc( type ) );
960                     
961             return "{fn CONVERT( " + createTimestampLiteral( timestamp ) + ", " + type_name + ") }";
962         } else {
963             throw new TKIllegalConversionException( "java.sql.Timestamp",
964                                                     "java.sql." + TYPE_NAMES.get( new Integer JavaDoc( type ) ) );
965         }
966     }
967     public String JavaDoc toString()
968     {
969         final StringBuffer JavaDoc buf = new StringBuffer JavaDoc();
970         String JavaDoc lineSep = System.getProperty("line.seperator");
971         
972         buf.append( "{\t" );
973         final Enumeration JavaDoc types_enum = db_types.elements();
974         while ( types_enum.hasMoreElements() ) {
975             buf.append( ((TypeInfo)types_enum.nextElement()).toString() );
976             if ( types_enum.hasMoreElements() )
977                 buf.append( "," );
978                 buf.append( lineSep );
979                 buf.append( "\t" );
980         }
981         buf.append( lineSep );
982         buf.append( "}" );
983         return buf.toString();
984     }
985     //{{DECLARE_CONTROLS
986
//}}
987
}
988
989
Popular Tags