source: Ballon/out/artifacts/geisa_artifact/WEB-INF/lib/mysql-connector-java-5.1.21/src/com/mysql/jdbc/Field.java @ 848

Last change on this file since 848 was 766, checked in by npipsl, 11 years ago
File size: 27.8 KB
Line 
1/*
2 Copyright (c) 2002, 2012, Oracle and/or its affiliates. All rights reserved.
3 
4
5 This program is free software; you can redistribute it and/or modify
6 it under the terms of version 2 of the GNU General Public License as
7 published by the Free Software Foundation.
8
9 There are special exceptions to the terms and conditions of the GPL
10 as it is applied to this software. View the full text of the
11 exception in file EXCEPTIONS-CONNECTOR-J in the directory of this
12 software distribution.
13
14 This program is distributed in the hope that it will be useful,
15 but WITHOUT ANY WARRANTY; without even the implied warranty of
16 MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
17 GNU General Public License for more details.
18
19 You should have received a copy of the GNU General Public License
20 along with this program; if not, write to the Free Software
21 Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA  02111-1307  USA
22
23
24
25 */
26package com.mysql.jdbc;
27
28import java.io.UnsupportedEncodingException;
29import java.sql.SQLException;
30import java.sql.Types;
31import java.util.regex.PatternSyntaxException;
32
33/**
34 * Field is a class used to describe fields in a ResultSet
35 *
36 * @author Mark Matthews
37 * @version $Id$
38 */
39public class Field {
40
41        private static final int AUTO_INCREMENT_FLAG = 512;
42
43        private static final int NO_CHARSET_INFO = -1;
44
45        private byte[] buffer;
46
47        private int charsetIndex = 0;
48
49        private String charsetName = null;
50
51        private int colDecimals;
52
53        private short colFlag;
54
55        private String collationName = null;
56
57        private MySQLConnection connection = null;
58
59        private String databaseName = null;
60
61        private int databaseNameLength = -1;
62
63        // database name info
64        private int databaseNameStart = -1;
65
66        protected int defaultValueLength = -1;
67
68        // default value info - from COM_LIST_FIELDS execution
69        protected int defaultValueStart = -1;
70
71        private String fullName = null;
72
73        private String fullOriginalName = null;
74
75        private boolean isImplicitTempTable = false;
76
77        private long length; // Internal length of the field;
78
79        private int mysqlType = -1; // the MySQL type
80
81        private String name; // The Field name
82
83        private int nameLength;
84
85        private int nameStart;
86
87        private String originalColumnName = null;
88
89        private int originalColumnNameLength = -1;
90
91        // column name info (before aliasing)
92        private int originalColumnNameStart = -1;
93
94        private String originalTableName = null;
95
96        private int originalTableNameLength = -1;
97
98        // table name info (before aliasing)
99        private int originalTableNameStart = -1;
100
101        private int precisionAdjustFactor = 0;
102
103        private int sqlType = -1; // the java.sql.Type
104
105        private String tableName; // The Name of the Table
106
107        private int tableNameLength;
108
109        private int tableNameStart;
110
111        private boolean useOldNameMetadata = false;
112
113        private boolean isSingleBit;
114
115        private int maxBytesPerChar;
116       
117        private final boolean valueNeedsQuoting;
118
119        /**
120         * Constructor used when communicating with 4.1 and newer servers
121         */
122        Field(MySQLConnection conn, byte[] buffer, int databaseNameStart,
123                        int databaseNameLength, int tableNameStart, int tableNameLength,
124                        int originalTableNameStart, int originalTableNameLength,
125                        int nameStart, int nameLength, int originalColumnNameStart,
126                        int originalColumnNameLength, long length, int mysqlType,
127                        short colFlag, int colDecimals, int defaultValueStart,
128                        int defaultValueLength, int charsetIndex) throws SQLException {
129                this.connection = conn;
130                this.buffer = buffer;
131                this.nameStart = nameStart;
132                this.nameLength = nameLength;
133                this.tableNameStart = tableNameStart;
134                this.tableNameLength = tableNameLength;
135                this.length = length;
136                this.colFlag = colFlag;
137                this.colDecimals = colDecimals;
138                this.mysqlType = mysqlType;
139
140                // 4.1 field info...
141                this.databaseNameStart = databaseNameStart;
142                this.databaseNameLength = databaseNameLength;
143
144                this.originalTableNameStart = originalTableNameStart;
145                this.originalTableNameLength = originalTableNameLength;
146
147                this.originalColumnNameStart = originalColumnNameStart;
148                this.originalColumnNameLength = originalColumnNameLength;
149
150                this.defaultValueStart = defaultValueStart;
151                this.defaultValueLength = defaultValueLength;
152
153                // If we're not running 4.1 or newer, use the connection's
154                // charset
155                this.charsetIndex = charsetIndex;
156
157
158                // Map MySqlTypes to java.sql Types
159                this.sqlType = MysqlDefs.mysqlToJavaType(this.mysqlType);
160
161        checkForImplicitTemporaryTable();
162                // Re-map to 'real' blob type, if we're a BLOB
163        boolean isFromFunction = this.originalTableNameLength == 0;
164       
165                if (this.mysqlType == MysqlDefs.FIELD_TYPE_BLOB) {
166                    if (this.connection != null && this.connection.getBlobsAreStrings() ||
167                            (this.connection.getFunctionsNeverReturnBlobs() && isFromFunction)) {
168                        this.sqlType = Types.VARCHAR;
169                        this.mysqlType = MysqlDefs.FIELD_TYPE_VARCHAR;
170                    } else if (this.charsetIndex == 63 ||
171                                        !this.connection.versionMeetsMinimum(4, 1, 0)) {
172                                if (this.connection.getUseBlobToStoreUTF8OutsideBMP() 
173                                                && shouldSetupForUtf8StringInBlob()) {
174                                        setupForUtf8StringInBlob();
175                                } else {
176                                        setBlobTypeBasedOnLength();
177                                        this.sqlType = MysqlDefs.mysqlToJavaType(this.mysqlType);
178                                }
179                        } else {
180                                // *TEXT masquerading as blob
181                                this.mysqlType = MysqlDefs.FIELD_TYPE_VAR_STRING;
182                                this.sqlType = Types.LONGVARCHAR;
183                        }
184                }
185
186                if (this.sqlType == Types.TINYINT && this.length == 1
187                                && this.connection.getTinyInt1isBit()) {
188                        // Adjust for pseudo-boolean
189                        if (conn.getTinyInt1isBit()) {
190                                if (conn.getTransformedBitIsBoolean()) {
191                                        this.sqlType = Types.BOOLEAN;
192                                } else {
193                                        this.sqlType = Types.BIT;
194                                }
195                        }
196
197                }
198
199                if (!isNativeNumericType() && !isNativeDateTimeType()) {
200                        this.charsetName = this.connection
201                                .getCharsetNameForIndex(this.charsetIndex);
202
203
204                        // Handle VARBINARY/BINARY (server doesn't have a different type
205                        // for this
206
207                        boolean isBinary = isBinary();
208
209                        if (this.connection.versionMeetsMinimum(4, 1, 0) &&
210                                        this.mysqlType == MysqlDefs.FIELD_TYPE_VAR_STRING &&
211                                        isBinary &&
212                                        this.charsetIndex == 63) {
213                                if (this.connection != null && (this.connection.getFunctionsNeverReturnBlobs() && isFromFunction)) {
214                                this.sqlType = Types.VARCHAR;
215                                this.mysqlType = MysqlDefs.FIELD_TYPE_VARCHAR;
216                                } else if (this.isOpaqueBinary()) {
217                                        this.sqlType = Types.VARBINARY;
218                                } 
219                        }
220
221                        if (this.connection.versionMeetsMinimum(4, 1, 0) &&
222                                        this.mysqlType == MysqlDefs.FIELD_TYPE_STRING &&
223                                        isBinary && this.charsetIndex == 63) {
224                                //
225                                // Okay, this is a hack, but there's currently no way
226                                // to easily distinguish something like DATE_FORMAT( ..)
227                                // from the "BINARY" column type, other than looking
228                                // at the original column name.
229                                //
230
231                                if (isOpaqueBinary() && !this.connection.getBlobsAreStrings()) {
232                                        this.sqlType = Types.BINARY;
233                                }
234                        }
235
236
237
238                        if (this.mysqlType == MysqlDefs.FIELD_TYPE_BIT) {
239                                this.isSingleBit = (this.length == 0);
240
241                                if (this.connection != null && (this.connection.versionMeetsMinimum(5, 0, 21) ||
242                                                this.connection.versionMeetsMinimum(5, 1, 10)) && this.length == 1) {
243                                        this.isSingleBit = true;
244                                }
245
246                                if (this.isSingleBit) {
247                                        this.sqlType = Types.BIT;
248                                } else {
249                                        this.sqlType = Types.VARBINARY;
250                                        this.colFlag |= 128; // we need to pretend this is a full
251                                        this.colFlag |= 16; // binary blob
252                                        isBinary = true;
253                                }
254                        }
255
256                        //
257                        // Handle TEXT type (special case), Fix proposed by Peter McKeown
258                        //
259                        if ((this.sqlType == java.sql.Types.LONGVARBINARY) && !isBinary) {
260                                this.sqlType = java.sql.Types.LONGVARCHAR;
261                        } else if ((this.sqlType == java.sql.Types.VARBINARY) && !isBinary) {
262                                this.sqlType = java.sql.Types.VARCHAR;
263                        }
264                } else {
265                        this.charsetName = "US-ASCII";
266                }
267
268                //
269                // Handle odd values for 'M' for floating point/decimal numbers
270                //
271                if (!isUnsigned()) {
272                        switch (this.mysqlType) {
273                        case MysqlDefs.FIELD_TYPE_DECIMAL:
274                        case MysqlDefs.FIELD_TYPE_NEW_DECIMAL:
275                                this.precisionAdjustFactor = -1;
276
277                                break;
278                        case MysqlDefs.FIELD_TYPE_DOUBLE:
279                        case MysqlDefs.FIELD_TYPE_FLOAT:
280                                this.precisionAdjustFactor = 1;
281
282                                break;
283                        }
284                } else {
285                        switch (this.mysqlType) {
286                        case MysqlDefs.FIELD_TYPE_DOUBLE:
287                        case MysqlDefs.FIELD_TYPE_FLOAT:
288                                this.precisionAdjustFactor = 1;
289
290                                break;
291                        }
292                }
293                this.valueNeedsQuoting = determineNeedsQuoting();
294        }
295
296        private boolean shouldSetupForUtf8StringInBlob() throws SQLException {
297                String includePattern = this.connection
298                                .getUtf8OutsideBmpIncludedColumnNamePattern();
299                String excludePattern = this.connection
300                                .getUtf8OutsideBmpExcludedColumnNamePattern();
301
302                if (excludePattern != null
303                                && !StringUtils.isEmptyOrWhitespaceOnly(excludePattern)) {
304                        try {
305                                if (getOriginalName().matches(excludePattern)) {
306                                        if (includePattern != null
307                                                        && !StringUtils.isEmptyOrWhitespaceOnly(includePattern)) {
308                                                try {
309                                                        if (getOriginalName().matches(includePattern)) {
310                                                                return true;
311                                                        }
312                                                } catch (PatternSyntaxException pse) {
313                                                        SQLException sqlEx = SQLError
314                                                                        .createSQLException(
315                                                                                        "Illegal regex specified for \"utf8OutsideBmpIncludedColumnNamePattern\"",
316                                                                                        SQLError.SQL_STATE_ILLEGAL_ARGUMENT, this.connection.getExceptionInterceptor());
317
318                                                        if (!this.connection.getParanoid()) {
319                                                                sqlEx.initCause(pse);
320                                                        }
321
322                                                        throw sqlEx;
323                                                }
324                                        }
325                                       
326                                        return false;
327                                }
328                        } catch (PatternSyntaxException pse) {
329                                SQLException sqlEx = SQLError
330                                                .createSQLException(
331                                                                "Illegal regex specified for \"utf8OutsideBmpExcludedColumnNamePattern\"",
332                                                                SQLError.SQL_STATE_ILLEGAL_ARGUMENT, this.connection.getExceptionInterceptor());
333
334                                if (!this.connection.getParanoid()) {
335                                        sqlEx.initCause(pse);
336                                }
337
338                                throw sqlEx;
339                        }
340                }
341
342                return true;
343        }
344
345        private void setupForUtf8StringInBlob() {
346                if (this.length == MysqlDefs.LENGTH_TINYBLOB || this.length == MysqlDefs.LENGTH_BLOB) {
347                        this.mysqlType = MysqlDefs.FIELD_TYPE_VARCHAR;
348                        this.sqlType = Types.VARCHAR;
349                }  else {
350                        this.mysqlType = MysqlDefs.FIELD_TYPE_VAR_STRING;
351                        this.sqlType = Types.LONGVARCHAR;
352                }
353               
354                this.charsetIndex = 33; 
355        }
356
357        /**
358         * Constructor used when communicating with pre 4.1 servers
359         */
360        Field(MySQLConnection conn, byte[] buffer, int nameStart, int nameLength,
361                        int tableNameStart, int tableNameLength, int length, int mysqlType,
362                        short colFlag, int colDecimals) throws SQLException {
363                this(conn, buffer, -1, -1, tableNameStart, tableNameLength, -1, -1,
364                                nameStart, nameLength, -1, -1, length, mysqlType, colFlag,
365                                colDecimals, -1, -1, NO_CHARSET_INFO);
366        }
367
368        /**
369         * Constructor used by DatabaseMetaData methods.
370         */
371        Field(String tableName, String columnName, int jdbcType, int length) {
372                this.tableName = tableName;
373                this.name = columnName;
374                this.length = length;
375                this.sqlType = jdbcType;
376                this.colFlag = 0;
377                this.colDecimals = 0;
378                this.valueNeedsQuoting = determineNeedsQuoting();
379        }
380       
381        /**
382         * Used by prepared statements to re-use result set data conversion methods
383         * when generating bound parmeter retrieval instance for statement
384         * interceptors.
385         *
386         * @param tableName
387         *            not used
388         * @param columnName
389         *            not used
390         * @param charsetIndex
391         *            the MySQL collation/character set index
392         * @param jdbcType
393         *            from java.sql.Types
394         * @param length
395         *            length in characters or bytes (for BINARY data).
396         */
397        Field(String tableName, String columnName, int charsetIndex, int jdbcType,
398                        int length) {
399                this.tableName = tableName;
400                this.name = columnName;
401                this.length = length;
402                this.sqlType = jdbcType;
403                this.colFlag = 0;
404                this.colDecimals = 0;
405                this.charsetIndex = charsetIndex;
406                this.valueNeedsQuoting = determineNeedsQuoting();
407               
408                switch (this.sqlType) {
409                case Types.BINARY:
410                case Types.VARBINARY:
411                        this.colFlag |= 128;
412                        this.colFlag |= 16;
413                        break;
414                }
415        }
416       
417        private void checkForImplicitTemporaryTable() {
418                this.isImplicitTempTable = this.tableNameLength > 5
419                                && this.buffer[tableNameStart] == (byte) '#'
420                                && this.buffer[tableNameStart + 1] == (byte) 's'
421                                && this.buffer[tableNameStart + 2] == (byte) 'q'
422                                && this.buffer[tableNameStart + 3] == (byte) 'l'
423                                && this.buffer[tableNameStart + 4] == (byte) '_';
424        }
425
426        /**
427         * Returns the character set (if known) for this field.
428         *
429         * @return the character set
430         */
431        public String getCharacterSet() throws SQLException {
432                return this.charsetName;
433        }
434
435        public void setCharacterSet(String javaEncodingName) throws SQLException {
436                this.charsetName = javaEncodingName;
437                try {
438                        this.charsetIndex = CharsetMapping
439                                .getCharsetIndexForMysqlEncodingName(javaEncodingName);
440                } catch (RuntimeException ex) {
441                        SQLException sqlEx = SQLError.createSQLException(ex.toString(), SQLError.SQL_STATE_ILLEGAL_ARGUMENT, null);
442                        sqlEx.initCause(ex);
443                        throw sqlEx;
444                }
445        }
446       
447        public synchronized String getCollation() throws SQLException {
448                if (this.collationName == null) {
449                        if (this.connection != null) {
450                                if (this.connection.versionMeetsMinimum(4, 1, 0)) {
451                                        if (this.connection.getUseDynamicCharsetInfo()) {
452                                                java.sql.DatabaseMetaData dbmd = this.connection
453                                                                .getMetaData();
454
455                                                String quotedIdStr = dbmd.getIdentifierQuoteString();
456
457                                                if (" ".equals(quotedIdStr)) { //$NON-NLS-1$
458                                                        quotedIdStr = ""; //$NON-NLS-1$
459                                                }
460
461                                                String csCatalogName = getDatabaseName();
462                                                String csTableName = getOriginalTableName();
463                                                String csColumnName = getOriginalName();
464
465                                                if (csCatalogName != null && csCatalogName.length() != 0
466                                                                && csTableName != null && csTableName.length() != 0
467                                                                && csColumnName != null
468                                                                && csColumnName.length() != 0) {
469                                                        StringBuffer queryBuf = new StringBuffer(csCatalogName
470                                                                        .length()
471                                                                        + csTableName.length() + 28);
472                                                        queryBuf.append("SHOW FULL COLUMNS FROM "); //$NON-NLS-1$
473                                                        queryBuf.append(quotedIdStr);
474                                                        queryBuf.append(csCatalogName);
475                                                        queryBuf.append(quotedIdStr);
476                                                        queryBuf.append("."); //$NON-NLS-1$
477                                                        queryBuf.append(quotedIdStr);
478                                                        queryBuf.append(csTableName);
479                                                        queryBuf.append(quotedIdStr);
480
481                                                        java.sql.Statement collationStmt = null;
482                                                        java.sql.ResultSet collationRs = null;
483
484                                                        try {
485                                                                collationStmt = this.connection.createStatement();
486
487                                                                collationRs = collationStmt.executeQuery(queryBuf
488                                                                                .toString());
489
490                                                                while (collationRs.next()) {
491                                                                        if (csColumnName.equals(collationRs
492                                                                                        .getString("Field"))) { //$NON-NLS-1$
493                                                                                this.collationName = collationRs
494                                                                                                .getString("Collation"); //$NON-NLS-1$
495
496                                                                                break;
497                                                                        }
498                                                                }
499                                                        } finally {
500                                                                if (collationRs != null) {
501                                                                        collationRs.close();
502                                                                        collationRs = null;
503                                                                }
504
505                                                                if (collationStmt != null) {
506                                                                        collationStmt.close();
507                                                                        collationStmt = null;
508                                                                }
509                                                        }
510                                                }
511                                        } else {
512                                                try {
513                                                        this.collationName = CharsetMapping.INDEX_TO_COLLATION[charsetIndex];
514                                                } catch (RuntimeException ex) {
515                                                        SQLException sqlEx = SQLError.createSQLException(ex.toString(), SQLError.SQL_STATE_ILLEGAL_ARGUMENT, null);
516                                                        sqlEx.initCause(ex);
517                                                        throw sqlEx;
518                                                }
519                                        }
520                                }
521                        }
522                }
523
524                return this.collationName;
525        }
526       
527        public String getColumnLabel() throws SQLException {
528                return getName(); // column name if not aliased, alias if used
529        }
530
531        /**
532         * DOCUMENT ME!
533         *
534         * @return DOCUMENT ME!
535         */
536        public String getDatabaseName() throws SQLException {
537                if ((this.databaseName == null) && (this.databaseNameStart != -1)
538                                && (this.databaseNameLength != -1)) {
539                        this.databaseName = getStringFromBytes(this.databaseNameStart,
540                                        this.databaseNameLength);
541                }
542
543                return this.databaseName;
544        }
545
546        int getDecimals() {
547                return this.colDecimals;
548        }
549
550        /**
551         * DOCUMENT ME!
552         *
553         * @return DOCUMENT ME!
554         */
555        public String getFullName() throws SQLException {
556                if (this.fullName == null) {
557                        StringBuffer fullNameBuf = new StringBuffer(getTableName().length()
558                                        + 1 + getName().length());
559                        fullNameBuf.append(this.tableName);
560
561                        // much faster to append a char than a String
562                        fullNameBuf.append('.');
563                        fullNameBuf.append(this.name);
564                        this.fullName = fullNameBuf.toString();
565                        fullNameBuf = null;
566                }
567
568                return this.fullName;
569        }
570
571        /**
572         * DOCUMENT ME!
573         *
574         * @return DOCUMENT ME!
575         */
576        public String getFullOriginalName() throws SQLException {
577                getOriginalName();
578
579                if (this.originalColumnName == null) {
580                        return null; // we don't have this information
581                }
582
583                if (this.fullName == null) {
584                        StringBuffer fullOriginalNameBuf = new StringBuffer(
585                                        getOriginalTableName().length() + 1
586                                                        + getOriginalName().length());
587                        fullOriginalNameBuf.append(this.originalTableName);
588
589                        // much faster to append a char than a String
590                        fullOriginalNameBuf.append('.');
591                        fullOriginalNameBuf.append(this.originalColumnName);
592                        this.fullOriginalName = fullOriginalNameBuf.toString();
593                        fullOriginalNameBuf = null;
594                }
595
596                return this.fullOriginalName;
597        }
598
599        /**
600         * DOCUMENT ME!
601         *
602         * @return DOCUMENT ME!
603         */
604        public long getLength() {
605                return this.length;
606        }
607
608        public synchronized int getMaxBytesPerCharacter() throws SQLException {
609                if (this.maxBytesPerChar == 0) {
610                        this.maxBytesPerChar = this.connection.getMaxBytesPerChar(this.charsetIndex, getCharacterSet());
611                }
612                return this.maxBytesPerChar;
613        }
614
615        /**
616         * DOCUMENT ME!
617         *
618         * @return DOCUMENT ME!
619         */
620        public int getMysqlType() {
621                return this.mysqlType;
622        }
623
624        /**
625         * DOCUMENT ME!
626         *
627         * @return DOCUMENT ME!
628         */
629        public String getName() throws SQLException {
630                if (this.name == null) {
631                        this.name = getStringFromBytes(this.nameStart, this.nameLength);
632                }
633
634                return this.name;
635        }
636
637        public String getNameNoAliases() throws SQLException {
638                if (this.useOldNameMetadata) {
639                        return getName();
640                }
641
642                if (this.connection != null &&
643                                this.connection.versionMeetsMinimum(4, 1, 0)) {
644                        return getOriginalName();
645                }
646
647                return getName();
648        }
649
650        /**
651         * DOCUMENT ME!
652         *
653         * @return DOCUMENT ME!
654         */
655        public String getOriginalName() throws SQLException {
656                if ((this.originalColumnName == null)
657                                && (this.originalColumnNameStart != -1)
658                                && (this.originalColumnNameLength != -1)) {
659                        this.originalColumnName = getStringFromBytes(
660                                        this.originalColumnNameStart, this.originalColumnNameLength);
661                }
662
663                return this.originalColumnName;
664        }
665
666        /**
667         * DOCUMENT ME!
668         *
669         * @return DOCUMENT ME!
670         */
671        public String getOriginalTableName() throws SQLException {
672                if ((this.originalTableName == null)
673                                && (this.originalTableNameStart != -1)
674                                && (this.originalTableNameLength != -1)) {
675                        this.originalTableName = getStringFromBytes(
676                                        this.originalTableNameStart, this.originalTableNameLength);
677                }
678
679                return this.originalTableName;
680        }
681
682        /**
683         * Returns amount of correction that should be applied to the precision
684         * value.
685         *
686         * Different versions of MySQL report different precision values.
687         *
688         * @return the amount to adjust precision value by.
689         */
690        public int getPrecisionAdjustFactor() {
691                return this.precisionAdjustFactor;
692        }
693
694        /**
695         * DOCUMENT ME!
696         *
697         * @return DOCUMENT ME!
698         */
699        public int getSQLType() {
700                return this.sqlType;
701        }
702
703        /**
704         * Create a string with the correct charset encoding from the byte-buffer
705         * that contains the data for this field
706         */
707        private String getStringFromBytes(int stringStart, int stringLength)
708                        throws SQLException {
709                if ((stringStart == -1) || (stringLength == -1)) {
710                        return null;
711                }
712
713                String stringVal = null;
714
715                if (this.connection != null) {
716                        if (this.connection.getUseUnicode()) {
717                                String encoding = this.connection.getCharacterSetMetadata();
718
719                                if (encoding == null) {
720                                        encoding = connection.getEncoding();
721                                }
722
723                                if (encoding != null) {
724                                        SingleByteCharsetConverter converter = null;
725
726                                        if (this.connection != null) {
727                                                converter = this.connection
728                                                                .getCharsetConverter(encoding);
729                                        }
730
731                                        if (converter != null) { // we have a converter
732                                                stringVal = converter.toString(this.buffer,
733                                                                stringStart, stringLength);
734                                        } else {
735                                                // we have no converter, use JVM converter
736                                                byte[] stringBytes = new byte[stringLength];
737
738                                                int endIndex = stringStart + stringLength;
739                                                int pos = 0;
740
741                                                for (int i = stringStart; i < endIndex; i++) {
742                                                        stringBytes[pos++] = this.buffer[i];
743                                                }
744
745                                                try {
746                                                        stringVal = StringUtils.toString(stringBytes, encoding);
747                                                } catch (UnsupportedEncodingException ue) {
748                                                        throw new RuntimeException(Messages
749                                                                        .getString("Field.12") + encoding //$NON-NLS-1$
750                                                                        + Messages.getString("Field.13")); //$NON-NLS-1$
751                                                }
752                                        }
753                                } else {
754                                        // we have no encoding, use JVM standard charset
755                                        stringVal = StringUtils.toAsciiString(this.buffer,
756                                                        stringStart, stringLength);
757                                }
758                        } else {
759                                // we are not using unicode, so use JVM standard charset
760                                stringVal = StringUtils.toAsciiString(this.buffer, stringStart,
761                                                stringLength);
762                        }
763                } else {
764                        // we don't have a connection, so punt
765                        stringVal = StringUtils.toAsciiString(this.buffer, stringStart,
766                                        stringLength);
767                }
768
769                return stringVal;
770        }
771
772        /**
773         * DOCUMENT ME!
774         *
775         * @return DOCUMENT ME!
776         */
777        public String getTable() throws SQLException {
778                return getTableName();
779        }
780
781        /**
782         * DOCUMENT ME!
783         *
784         * @return DOCUMENT ME!
785         */
786        public String getTableName() throws SQLException {
787                if (this.tableName == null) {
788                        this.tableName = getStringFromBytes(this.tableNameStart,
789                                        this.tableNameLength);
790                }
791
792                return this.tableName;
793        }
794
795        public String getTableNameNoAliases() throws SQLException {
796                if (this.connection.versionMeetsMinimum(4, 1, 0)) {
797                        return getOriginalTableName();
798                }
799
800                return getTableName(); // pre-4.1, no aliases returned
801        }
802
803        /**
804         * DOCUMENT ME!
805         *
806         * @return DOCUMENT ME!
807         */
808        public boolean isAutoIncrement() {
809                return ((this.colFlag & AUTO_INCREMENT_FLAG) > 0);
810        }
811
812        /**
813         * DOCUMENT ME!
814         *
815         * @return DOCUMENT ME!
816         */
817        public boolean isBinary() {
818                return ((this.colFlag & 128) > 0);
819        }
820
821        /**
822         * DOCUMENT ME!
823         *
824         * @return DOCUMENT ME!
825         */
826        public boolean isBlob() {
827                return ((this.colFlag & 16) > 0);
828        }
829
830        /**
831         * Is this field owned by a server-created temporary table?
832         *
833         * @return
834         */
835        private boolean isImplicitTemporaryTable() {
836                return this.isImplicitTempTable;
837        }
838
839        /**
840         * DOCUMENT ME!
841         *
842         * @return DOCUMENT ME!
843         */
844        public boolean isMultipleKey() {
845                return ((this.colFlag & 8) > 0);
846        }
847
848        boolean isNotNull() {
849                return ((this.colFlag & 1) > 0);
850        }
851
852        boolean isOpaqueBinary() throws SQLException {
853
854                //
855                // Detect CHAR(n) CHARACTER SET BINARY which is a synonym for
856                // fixed-length binary types
857                //
858
859                if (this.charsetIndex == 63 && isBinary()
860                                && (this.getMysqlType() == MysqlDefs.FIELD_TYPE_STRING ||
861                                this.getMysqlType() == MysqlDefs.FIELD_TYPE_VAR_STRING)) {
862
863                        if (this.originalTableNameLength == 0 && (
864                                        this.connection != null && !this.connection.versionMeetsMinimum(5, 0, 25))) {
865                                return false; // Probably from function
866                        }
867
868                        // Okay, queries resolved by temp tables also have this 'signature',
869                        // check for that
870
871                        return !isImplicitTemporaryTable();
872                }
873
874                return (this.connection.versionMeetsMinimum(4, 1, 0) && "binary"
875                                .equalsIgnoreCase(getCharacterSet()));
876
877        }
878
879        /**
880         * DOCUMENT ME!
881         *
882         * @return DOCUMENT ME!
883         */
884        public boolean isPrimaryKey() {
885                return ((this.colFlag & 2) > 0);
886        }
887
888        /**
889         * Is this field _definitely_ not writable?
890         *
891         * @return true if this field can not be written to in an INSERT/UPDATE
892         *         statement.
893         */
894        boolean isReadOnly() throws SQLException {
895                if (this.connection.versionMeetsMinimum(4, 1, 0)) {
896                        String orgColumnName = getOriginalName();
897                        String orgTableName = getOriginalTableName();
898
899                        return !(orgColumnName != null && orgColumnName.length() > 0
900                                        && orgTableName != null && orgTableName.length() > 0);
901                }
902
903                return false; // we can't tell definitively in this case.
904        }
905
906        /**
907         * DOCUMENT ME!
908         *
909         * @return DOCUMENT ME!
910         */
911        public boolean isUniqueKey() {
912                return ((this.colFlag & 4) > 0);
913        }
914
915        /**
916         * DOCUMENT ME!
917         *
918         * @return DOCUMENT ME!
919         */
920        public boolean isUnsigned() {
921                return ((this.colFlag & 32) > 0);
922        }
923
924        public void setUnsigned() {
925                this.colFlag |= 32;
926        }
927       
928        /**
929         * DOCUMENT ME!
930         *
931         * @return DOCUMENT ME!
932         */
933        public boolean isZeroFill() {
934                return ((this.colFlag & 64) > 0);
935        }
936
937        //
938        // MySQL only has one protocol-level BLOB type that it exposes
939        // which is FIELD_TYPE_BLOB, although we can divine what the
940        // actual type is by the length reported ...
941        //
942        private void setBlobTypeBasedOnLength() {
943                if (this.length == MysqlDefs.LENGTH_TINYBLOB) {
944                        this.mysqlType = MysqlDefs.FIELD_TYPE_TINY_BLOB;
945                } else if (this.length == MysqlDefs.LENGTH_BLOB) {
946                        this.mysqlType = MysqlDefs.FIELD_TYPE_BLOB;
947                } else if (this.length == MysqlDefs.LENGTH_MEDIUMBLOB) {
948                        this.mysqlType = MysqlDefs.FIELD_TYPE_MEDIUM_BLOB;
949                } else if (this.length == MysqlDefs.LENGTH_LONGBLOB) {
950                        this.mysqlType = MysqlDefs.FIELD_TYPE_LONG_BLOB;
951                }
952        }
953
954        private boolean isNativeNumericType() {
955                return ((this.mysqlType >= MysqlDefs.FIELD_TYPE_TINY &&
956                                        this.mysqlType <= MysqlDefs.FIELD_TYPE_DOUBLE) ||
957                                        this.mysqlType == MysqlDefs.FIELD_TYPE_LONGLONG ||
958                                        this.mysqlType == MysqlDefs.FIELD_TYPE_YEAR);
959        }
960
961        private boolean isNativeDateTimeType() {
962                return (this.mysqlType == MysqlDefs.FIELD_TYPE_DATE ||
963                                this.mysqlType == MysqlDefs.FIELD_TYPE_NEWDATE ||
964                                this.mysqlType == MysqlDefs.FIELD_TYPE_DATETIME ||
965                                this.mysqlType == MysqlDefs.FIELD_TYPE_TIME ||
966                                this.mysqlType == MysqlDefs.FIELD_TYPE_TIMESTAMP);
967        }
968
969        /**
970         * DOCUMENT ME!
971         *
972         * @param conn
973         *            DOCUMENT ME!
974         */
975        public void setConnection(MySQLConnection conn) {
976                this.connection = conn;
977
978                if (this.charsetName == null || this.charsetIndex == 0) {
979                        this.charsetName = this.connection.getEncoding();
980                }
981        }
982
983        void setMysqlType(int type) {
984                this.mysqlType = type;
985                this.sqlType = MysqlDefs.mysqlToJavaType(this.mysqlType);
986        }
987
988        protected void setUseOldNameMetadata(boolean useOldNameMetadata) {
989                this.useOldNameMetadata = useOldNameMetadata;
990        }
991
992        public String toString() {
993                try {
994                        StringBuffer asString = new StringBuffer();
995                        asString.append(super.toString());
996                        asString.append("[");
997                        asString.append("catalog=");
998                        asString.append(this.getDatabaseName());
999                        asString.append(",tableName=");
1000                        asString.append(this.getTableName());
1001                        asString.append(",originalTableName=");
1002                        asString.append(this.getOriginalTableName());
1003                        asString.append(",columnName=");
1004                        asString.append(this.getName());
1005                        asString.append(",originalColumnName=");
1006                        asString.append(this.getOriginalName());
1007                        asString.append(",mysqlType=");
1008                        asString.append(getMysqlType());
1009                        asString.append("(");
1010                        asString.append(MysqlDefs.typeToName(getMysqlType()));
1011                        asString.append(")");
1012                        asString.append(",flags=");
1013                       
1014                        if (isAutoIncrement()) {
1015                                asString.append(" AUTO_INCREMENT");
1016                        }
1017                       
1018                        if (isPrimaryKey()) {
1019                                asString.append(" PRIMARY_KEY");
1020                        }
1021                       
1022                        if (isUniqueKey()) {
1023                                asString.append(" UNIQUE_KEY");
1024                        }
1025                       
1026                        if (isBinary()) {
1027                                asString.append(" BINARY");
1028                        }
1029                       
1030                        if (isBlob()) {
1031                                asString.append(" BLOB");
1032                        }
1033                       
1034                        if (isMultipleKey()) {
1035                                asString.append(" MULTI_KEY");
1036                        }
1037                       
1038                        if (isUnsigned()) {
1039                                asString.append(" UNSIGNED");
1040                        }
1041                       
1042                        if (isZeroFill()) {
1043                                asString.append(" ZEROFILL");
1044                        }
1045
1046                        asString.append(", charsetIndex=");
1047                        asString.append(this.charsetIndex);
1048                        asString.append(", charsetName=");
1049                        asString.append(this.charsetName);
1050                       
1051                       
1052                        //if (this.buffer != null) {
1053                        //      asString.append("\n\nData as received from server:\n\n");
1054                        //      asString.append(StringUtils.dumpAsHex(this.buffer,
1055                        //                      this.buffer.length));
1056                        //}
1057
1058                        asString.append("]");
1059                       
1060                        return asString.toString();
1061                } catch (Throwable t) {
1062                        return super.toString();
1063                }
1064        }
1065
1066        protected boolean isSingleBit() {
1067                return this.isSingleBit;
1068        }
1069
1070        protected boolean getvalueNeedsQuoting() {
1071                return this.valueNeedsQuoting;
1072        }
1073
1074        private boolean determineNeedsQuoting() {
1075                boolean retVal = false;
1076               
1077                switch (this.sqlType) {
1078                case Types.BIGINT:
1079                case Types.BIT:
1080                case Types.DECIMAL:
1081                case Types.DOUBLE:
1082                case Types.FLOAT:
1083                case Types.INTEGER:
1084                case Types.NUMERIC:
1085                case Types.REAL:
1086                case Types.SMALLINT:
1087                case Types.TINYINT:
1088                        retVal = false;
1089                        break;
1090                default: 
1091                        retVal = true;
1092                }
1093                return retVal;
1094
1095        }
1096}
Note: See TracBrowser for help on using the repository browser.