KickJava   Java API By Example, From Geeks To Geeks.

Java > Open Source Codes > com > mysql > jdbc > Field


1 /*
2    Copyright (C) 2002 MySQL AB
3
4       This program is free software; you can redistribute it and/or modify
5       it under the terms of the GNU General Public License as published by
6       the Free Software Foundation; either version 2 of the License, or
7       (at your option) any later version.
8
9       This program is distributed in the hope that it will be useful,
10       but WITHOUT ANY WARRANTY; without even the implied warranty of
11       MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
12       GNU General Public License for more details.
13
14       You should have received a copy of the GNU General Public License
15       along with this program; if not, write to the Free Software
16       Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA
17
18  */

19 package com.mysql.jdbc;
20
21 import java.io.UnsupportedEncodingException JavaDoc;
22
23
24 /**
25  * Field is a class used to describe fields in a
26  * ResultSet
27  *
28  * @author Mark Matthews
29  * @version $Id: Field.java,v 1.15.2.6 2004/02/06 00:54:16 mmatthew Exp $
30  */

31 public class Field {
32     //~ Static fields/initializers ---------------------------------------------
33

34     private static final int AUTO_INCREMENT_FLAG = 512;
35     private static final int NO_CHARSET_INFO = -1;
36
37     //~ Instance fields --------------------------------------------------------
38

39     private Connection connection = null;
40     private String JavaDoc charsetName = null;
41     private String JavaDoc databaseName = null;
42     private String JavaDoc defaultValue = null;
43     private String JavaDoc fullName = null;
44     private String JavaDoc fullNameWithDatabase = null;
45     private String JavaDoc fullOriginalName = null;
46     private String JavaDoc fullOriginalNameWithDatabase = null;
47     private String JavaDoc name; // The Field name
48
private String JavaDoc originalColumnName = null;
49     private String JavaDoc originalTableName = null;
50     private String JavaDoc tableName; // The Name of the Table
51
private byte[] buffer;
52     private int charsetIndex = 0;
53     private int colDecimals;
54     private int databaseNameLength = -1;
55
56     // database name info
57
private int databaseNameStart = -1;
58     private int defaultValueLength = -1;
59
60     // default value info - from COM_LIST_FIELDS execution
61
private int defaultValueStart = -1;
62     private int length; // Internal length of the field;
63
private int mysqlType = -1; // the MySQL type
64
private int nameLength;
65     private int nameStart;
66     private int originalColumnNameLength = -1;
67
68     // column name info (before aliasing)
69
private int originalColumnNameStart = -1;
70     private int originalTableNameLength = -1;
71
72     // table name info (before aliasing)
73
private int originalTableNameStart = -1;
74     private int precisionAdjustFactor = 0;
75     private int sqlType = -1; // the java.sql.Type
76
private int tableNameLength;
77     private int tableNameStart;
78     private short colFlag;
79
80     //~ Constructors -----------------------------------------------------------
81

82     /**
83     * Constructor used by DatabaseMetaData methods.
84     */

85     Field(String JavaDoc tableName, String JavaDoc columnName, int jdbcType, int length) {
86         this.tableName = tableName;
87         this.name = columnName;
88         this.length = length;
89         sqlType = jdbcType;
90         colFlag = 0;
91         colDecimals = 0;
92     }
93
94     /**
95      * Constructor used when communicating with pre 4.1 servers
96      */

97     Field(Connection conn, byte[] buffer, int nameStart, int nameLength,
98         int tableNameStart, int tableNameLength, int length, int mysqlType,
99         short colFlag, int colDecimals) {
100         this(conn, buffer, -1, -1, tableNameStart, tableNameLength, -1, -1,
101             nameStart, nameLength, -1, -1, length, mysqlType, colFlag,
102             colDecimals, -1, -1, NO_CHARSET_INFO);
103     }
104
105     /**
106      * Constructor used when communicating with 4.1 and newer
107      * servers
108      */

109     Field(Connection conn, byte[] buffer, int databaseNameStart,
110         int databaseNameLength, int tableNameStart, int tableNameLength,
111         int originalTableNameStart, int originalTableNameLength, int nameStart,
112         int nameLength, int originalColumnNameStart,
113         int originalColumnNameLength, int length, int mysqlType, short colFlag,
114         int colDecimals, int defaultValueStart, int defaultValueLength,
115         int charsetIndex) {
116         this.connection = conn;
117         this.buffer = buffer;
118         this.nameStart = nameStart;
119         this.nameLength = nameLength;
120         this.tableNameStart = tableNameStart;
121         this.tableNameLength = tableNameLength;
122         this.length = length;
123         this.colFlag = colFlag;
124         this.colDecimals = colDecimals;
125         this.mysqlType = mysqlType;
126
127         // 4.1 field info...
128
this.databaseNameStart = databaseNameStart;
129         this.databaseNameLength = databaseNameLength;
130
131         this.originalTableNameStart = originalTableNameStart;
132         this.originalTableNameLength = originalTableNameLength;
133
134         this.originalColumnNameStart = originalColumnNameStart;
135         this.originalColumnNameLength = originalColumnNameLength;
136
137         this.defaultValueStart = defaultValueStart;
138         this.defaultValueLength = defaultValueLength;
139
140         // Map MySqlTypes to java.sql Types
141
sqlType = MysqlDefs.mysqlToJavaType(mysqlType);
142
143         // If we're not running 4.1 or newer, use the connection's
144
// charset
145
if (charsetIndex != NO_CHARSET_INFO) {
146             this.charsetIndex = charsetIndex;
147             this.charsetName = CharsetMapping.INDEX_TO_CHARSET[this.charsetIndex];
148             
149             // Punt
150
if (this.charsetName == null) {
151                 this.charsetName = this.connection.getEncoding();
152             }
153         } else {
154             this.charsetName = this.connection.getEncoding();
155         }
156
157         boolean isBinary = isBinary();
158
159         //
160
// Handle TEXT type (special case), Fix proposed by Peter McKeown
161
//
162
if ((sqlType == java.sql.Types.LONGVARBINARY) && !isBinary) {
163             sqlType = java.sql.Types.LONGVARCHAR;
164         } else if ((sqlType == java.sql.Types.VARBINARY) && !isBinary) {
165             sqlType = java.sql.Types.VARCHAR;
166         }
167
168         //
169
// Handle odd values for 'M' for floating point/decimal numbers
170
//
171
if (!isUnsigned()) {
172             switch (this.mysqlType) {
173             case MysqlDefs.FIELD_TYPE_DECIMAL:
174                 this.precisionAdjustFactor = -1;
175
176                 break;
177
178             case MysqlDefs.FIELD_TYPE_DOUBLE:
179             case MysqlDefs.FIELD_TYPE_FLOAT:
180                 this.precisionAdjustFactor = 1;
181
182                 break;
183             }
184         } else {
185             switch (this.mysqlType) {
186             case MysqlDefs.FIELD_TYPE_DOUBLE:
187             case MysqlDefs.FIELD_TYPE_FLOAT:
188                 this.precisionAdjustFactor = 1;
189
190                 break;
191             }
192         }
193     }
194
195     //~ Methods ----------------------------------------------------------------
196

197     /**
198      * DOCUMENT ME!
199      *
200      * @return DOCUMENT ME!
201      */

202     public boolean isAutoIncrement() {
203         return ((colFlag & AUTO_INCREMENT_FLAG) > 0);
204     }
205
206     /**
207      * DOCUMENT ME!
208      *
209      * @return DOCUMENT ME!
210      */

211     public boolean isBinary() {
212         return ((colFlag & 128) > 0);
213     }
214
215     /**
216      * DOCUMENT ME!
217      *
218      * @return DOCUMENT ME!
219      */

220     public boolean isBlob() {
221         return ((colFlag & 16) > 0);
222     }
223
224     /**
225      * Returns the character set (if known) for this
226      * field.
227      *
228      * @return the character set
229      */

230     public String JavaDoc getCharacterSet() {
231         return this.charsetName;
232     }
233
234     /**
235      * DOCUMENT ME!
236      *
237      * @param conn DOCUMENT ME!
238      */

239     public void setConnection(Connection conn) {
240         this.connection = conn;
241         
242         this.charsetName = this.connection.getEncoding();
243     }
244
245     /**
246      * DOCUMENT ME!
247      *
248      * @return DOCUMENT ME!
249      */

250     public String JavaDoc getDatabaseName() {
251         if ((this.databaseName == null) && (this.databaseNameStart != -1)
252                 && (this.databaseNameLength != -1)) {
253             this.databaseName = getStringFromBytes(this.databaseNameStart,
254                     this.databaseNameLength);
255         }
256
257         return this.databaseName;
258     }
259
260     /**
261      * DOCUMENT ME!
262      *
263      * @return DOCUMENT ME!
264      */

265     public String JavaDoc getFullName() {
266         if (fullName == null) {
267             StringBuffer JavaDoc fullNameBuf = new StringBuffer JavaDoc(getTableName().length()
268                     + 1 + getName().length());
269             fullNameBuf.append(tableName);
270
271             // much faster to append a char than a String
272
fullNameBuf.append('.');
273             fullNameBuf.append(name);
274             fullName = fullNameBuf.toString();
275             fullNameBuf = null;
276         }
277
278         return fullName;
279     }
280
281     /**
282      * DOCUMENT ME!
283      *
284      * @return DOCUMENT ME!
285      */

286     public String JavaDoc getFullOriginalName() {
287         getOriginalName();
288
289         if (this.originalColumnName == null) {
290             return null; // we don't have this information
291
}
292
293         if (fullName == null) {
294             StringBuffer JavaDoc fullOriginalNameBuf = new StringBuffer JavaDoc(getOriginalTableName()
295                                                                     .length()
296                     + 1 + getOriginalName().length());
297             fullOriginalNameBuf.append(this.originalTableName);
298
299             // much faster to append a char than a String
300
fullOriginalNameBuf.append('.');
301             fullOriginalNameBuf.append(this.originalColumnName);
302             this.fullOriginalName = fullOriginalNameBuf.toString();
303             fullOriginalNameBuf = null;
304         }
305
306         return this.fullOriginalName;
307     }
308
309     /**
310      * DOCUMENT ME!
311      *
312      * @return DOCUMENT ME!
313      */

314     public int getLength() {
315         return length;
316     }
317
318     /**
319      * DOCUMENT ME!
320      *
321      * @return DOCUMENT ME!
322      */

323     public boolean isMultipleKey() {
324         return ((colFlag & 8) > 0);
325     }
326
327     /**
328      * DOCUMENT ME!
329      *
330      * @return DOCUMENT ME!
331      */

332     public int getMysqlType() {
333         return mysqlType;
334     }
335
336     /**
337      * DOCUMENT ME!
338      *
339      * @return DOCUMENT ME!
340      */

341     public String JavaDoc getName() {
342         if (this.name == null) {
343             this.name = getStringFromBytes(this.nameStart, this.nameLength);
344         }
345
346         return name;
347     }
348
349     /**
350      * DOCUMENT ME!
351      *
352      * @return DOCUMENT ME!
353      */

354     public String JavaDoc getOriginalName() {
355         if ((this.originalColumnName == null)
356                 && (this.originalColumnNameStart != -1)
357                 && (this.originalColumnNameLength != -1)) {
358             this.originalColumnName = getStringFromBytes(this.originalColumnNameStart,
359                     this.originalColumnNameLength);
360         }
361
362         return this.originalColumnName;
363     }
364
365     /**
366      * DOCUMENT ME!
367      *
368      * @return DOCUMENT ME!
369      */

370     public String JavaDoc getOriginalTableName() {
371         if ((this.originalTableName == null)
372                 && (this.originalTableNameStart != -1)
373                 && (this.originalTableNameLength != -1)) {
374             this.originalTableName = getStringFromBytes(this.originalTableNameStart,
375                     this.originalTableNameLength);
376         }
377
378         return this.originalTableName;
379     }
380
381     /**
382      * Returns amount of correction that
383      * should be applied to the precision value.
384      *
385      * Different versions of MySQL report different
386      * precision values.
387      *
388      * @return the amount to adjust precision value by.
389      */

390     public int getPrecisionAdjustFactor() {
391         return this.precisionAdjustFactor;
392     }
393
394     /**
395      * DOCUMENT ME!
396      *
397      * @return DOCUMENT ME!
398      */

399     public boolean isPrimaryKey() {
400         return ((colFlag & 2) > 0);
401     }
402
403     /**
404      * DOCUMENT ME!
405      *
406      * @return DOCUMENT ME!
407      */

408     public int getSQLType() {
409         return sqlType;
410     }
411
412     /**
413      * DOCUMENT ME!
414      *
415      * @return DOCUMENT ME!
416      */

417     public String JavaDoc getTable() {
418         return getTableName();
419     }
420
421     /**
422      * DOCUMENT ME!
423      *
424      * @return DOCUMENT ME!
425      */

426     public String JavaDoc getTableName() {
427         if (tableName == null) {
428             tableName = getStringFromBytes(tableNameStart, tableNameLength);
429         }
430
431         return tableName;
432     }
433
434     /**
435      * DOCUMENT ME!
436      *
437      * @return DOCUMENT ME!
438      */

439     public boolean isUniqueKey() {
440         return ((colFlag & 4) > 0);
441     }
442
443     /**
444      * DOCUMENT ME!
445      *
446      * @return DOCUMENT ME!
447      */

448     public boolean isUnsigned() {
449         return ((colFlag & 32) > 0);
450     }
451
452     /**
453      * DOCUMENT ME!
454      *
455      * @return DOCUMENT ME!
456      */

457     public boolean isZeroFill() {
458         return ((colFlag & 64) > 0);
459     }
460
461     /**
462      * DOCUMENT ME!
463      *
464      * @return DOCUMENT ME!
465      */

466     public String JavaDoc toString() {
467         return this.getDatabaseName() + " . " + this.getTableName() + "(" + this.getOriginalTableName() + ") . " + this.getName() + "(" + this.getOriginalName() + ")";
468        
469     }
470
471     int getDecimals() {
472         return colDecimals;
473     }
474
475     boolean isNotNull() {
476         return ((colFlag & 1) > 0);
477     }
478
479     /**
480      * Create a string with the correct charset encoding from the
481      * byte-buffer that contains the data for this field
482      */

483     private String JavaDoc getStringFromBytes(int stringStart, int stringLength) {
484         if ((stringStart == -1) || (stringLength == -1)) {
485             return null;
486         }
487
488         String JavaDoc stringVal = null;
489
490         if (connection != null) {
491             if (connection.useUnicode()) {
492                 String JavaDoc encoding = connection.getEncoding();
493
494                 if (encoding != null) {
495                    
496                     SingleByteCharsetConverter converter = null;
497                     
498                     if (this.connection != null) {
499                         converter = this.connection.getCharsetConverter(encoding);
500                     }
501                     
502                     if (converter != null) { // we have a converter
503
stringVal = converter.toString(buffer, stringStart,
504                                 stringLength);
505                     } else {
506                         // we have no converter, use JVM converter
507
byte[] stringBytes = new byte[stringLength];
508
509                         int endIndex = stringStart + stringLength;
510                         int pos = 0;
511
512                         for (int i = stringStart; i < endIndex; i++) {
513                             stringBytes[pos++] = buffer[i];
514                         }
515
516                         try {
517                             stringVal = new String JavaDoc(stringBytes, encoding);
518                         } catch (UnsupportedEncodingException JavaDoc ue) {
519                             throw new RuntimeException JavaDoc(
520                                 "Unsupported character encoding '" + encoding
521                                 + "'");
522                         }
523                     }
524                 } else {
525                     // we have no encoding, use JVM standard charset
526
stringVal = StringUtils.toAsciiString(buffer, stringStart,
527                             stringLength);
528                 }
529             } else {
530                 // we are not using unicode, so use JVM standard charset
531
stringVal = StringUtils.toAsciiString(buffer, stringStart,
532                         stringLength);
533             }
534         } else {
535             // we don't have a connection, so punt
536
stringVal = StringUtils.toAsciiString(buffer, stringStart,
537                     stringLength);
538         }
539
540         return stringVal;
541     }
542 }
543
Popular Tags