~ubuntu-branches/ubuntu/karmic/mysql-connector-java/karmic

« back to all changes in this revision

Viewing changes to com/mysql/jdbc/Field.java

  • Committer: Bazaar Package Importer
  • Author(s): Takashi Okamoto
  • Date: 2003-12-30 22:37:53 UTC
  • Revision ID: james.westby@ubuntu.com-20031230223753-5d9n2b0w2ms6puqa
Tags: upstream-3.0.9
ImportĀ upstreamĀ versionĀ 3.0.9

Show diffs side-by-side

added added

removed removed

Lines of Context:
 
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;
 
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.4 2003/03/21 13:43:50 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 charsetName = null;
 
41
    private String databaseName = null;
 
42
    private String defaultValue = null;
 
43
    private String fullName = null;
 
44
    private String fullNameWithDatabase = null;
 
45
    private String fullOriginalName = null;
 
46
    private String fullOriginalNameWithDatabase = null;
 
47
    private String name; // The Field name
 
48
    private String originalColumnName = null;
 
49
    private String originalTableName = null;
 
50
    private String 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 tableName, String 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 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 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 getFullName() {
 
266
        if (fullName == null) {
 
267
            StringBuffer fullNameBuf = new StringBuffer(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 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 fullOriginalNameBuf = new StringBuffer(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 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 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 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 getTable() {
 
418
        return getTableName();
 
419
    }
 
420
 
 
421
    /**
 
422
     * DOCUMENT ME!
 
423
     *
 
424
     * @return DOCUMENT ME!
 
425
     */
 
426
    public String 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 toString() {
 
467
        return getFullName();
 
468
    }
 
469
 
 
470
    int getDecimals() {
 
471
        return colDecimals;
 
472
    }
 
473
 
 
474
    boolean isNotNull() {
 
475
        return ((colFlag & 1) > 0);
 
476
    }
 
477
 
 
478
    /**
 
479
     * Create a string with the correct charset encoding from the
 
480
     * byte-buffer that contains the data for this field
 
481
     */
 
482
    private String getStringFromBytes(int stringStart, int stringLength) {
 
483
        if ((stringStart == -1) || (stringLength == -1)) {
 
484
            return null;
 
485
        }
 
486
 
 
487
        String stringVal = null;
 
488
 
 
489
        if (connection != null) {
 
490
            if (connection.useUnicode()) {
 
491
                String encoding = connection.getEncoding();
 
492
 
 
493
                if (encoding != null) {
 
494
                    SingleByteCharsetConverter converter = null;
 
495
 
 
496
                    try {
 
497
                        converter = SingleByteCharsetConverter.getInstance(encoding);
 
498
                    } catch (UnsupportedEncodingException uee) {
 
499
                        // ignore, code further down handles this
 
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(stringBytes, encoding);
 
518
                        } catch (UnsupportedEncodingException ue) {
 
519
                            throw new RuntimeException(
 
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
}