001: /*
002:
003: Derby - Class org.apache.derby.iapi.types.DataTypeUtilities
004:
005: Licensed to the Apache Software Foundation (ASF) under one or more
006: contributor license agreements. See the NOTICE file distributed with
007: this work for additional information regarding copyright ownership.
008: The ASF licenses this file to you under the Apache License, Version 2.0
009: (the "License"); you may not use this file except in compliance with
010: the License. You may obtain a copy of the License at
011:
012: http://www.apache.org/licenses/LICENSE-2.0
013:
014: Unless required by applicable law or agreed to in writing, software
015: distributed under the License is distributed on an "AS IS" BASIS,
016: WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
017: See the License for the specific language governing permissions and
018: limitations under the License.
019:
020: */
021:
022: package org.apache.derby.iapi.types;
023:
024: import org.apache.derby.iapi.error.StandardException;
025:
026: import org.apache.derby.iapi.reference.JDBC30Translation;
027: import org.apache.derby.iapi.services.io.StoredFormatIds;
028:
029: import java.sql.Types;
030: import java.sql.ResultSetMetaData;
031:
032: /**
033: A set of static utility methods for data types.
034: * @author djd
035: */
036: public abstract class DataTypeUtilities {
037:
038: /**
039: Get the precision of the datatype.
040: @param dtd data type descriptor
041: */
042: public static int getPrecision(DataTypeDescriptor dtd) {
043: int typeId = dtd.getTypeId().getJDBCTypeId();
044:
045: switch (typeId) {
046: case Types.CHAR: // CHAR et alia return their # characters...
047: case Types.VARCHAR:
048: case Types.LONGVARCHAR:
049: case Types.CLOB:
050: case Types.BINARY: // BINARY types return their # bytes...
051: case Types.VARBINARY:
052: case Types.LONGVARBINARY:
053: case Types.BLOB:
054: case StoredFormatIds.XML_TYPE_ID:
055: return dtd.getMaximumWidth();
056: case Types.SMALLINT:
057: return 5;
058: case JDBC30Translation.SQL_TYPES_BOOLEAN:
059: return 1;
060: }
061:
062: return dtd.getPrecision();
063: }
064:
065: /**
066: Get the precision of the datatype, in decimal digits
067: This is used by EmbedResultSetMetaData.
068: @param dtd data type descriptor
069: */
070: public static int getDigitPrecision(DataTypeDescriptor dtd) {
071: int typeId = dtd.getTypeId().getJDBCTypeId();
072:
073: switch (typeId) {
074: case Types.FLOAT:
075: case Types.DOUBLE:
076: return TypeId.DOUBLE_PRECISION_IN_DIGITS;
077: case Types.REAL:
078: return TypeId.REAL_PRECISION_IN_DIGITS;
079: default:
080: return getPrecision(dtd);
081: }
082:
083: }
084:
085: /**
086: Is the data type currency.
087: @param dtd data type descriptor
088: */
089: public static boolean isCurrency(DataTypeDescriptor dtd) {
090: int typeId = dtd.getTypeId().getJDBCTypeId();
091:
092: // Only the NUMERIC and DECIMAL types are currency
093: return ((typeId == Types.DECIMAL) || (typeId == Types.NUMERIC));
094: }
095:
096: /**
097: Is the data type case sensitive.
098: @param dtd data type descriptor
099: */
100: public static boolean isCaseSensitive(DataTypeDescriptor dtd) {
101: int typeId = dtd.getTypeId().getJDBCTypeId();
102:
103: return (typeId == Types.CHAR || typeId == Types.VARCHAR
104: || typeId == Types.CLOB || typeId == Types.LONGVARCHAR || typeId == StoredFormatIds.XML_TYPE_ID);
105: }
106:
107: /**
108: Is the data type nullable.
109: @param dtd data type descriptor
110: */
111: public static int isNullable(DataTypeDescriptor dtd) {
112: return dtd.isNullable() ? ResultSetMetaData.columnNullable
113: : ResultSetMetaData.columnNoNulls;
114: }
115:
116: /**
117: Is the data type signed.
118: @param dtd data type descriptor
119: */
120: public static boolean isSigned(DataTypeDescriptor dtd) {
121: int typeId = dtd.getTypeId().getJDBCTypeId();
122:
123: return (typeId == Types.INTEGER || typeId == Types.FLOAT
124: || typeId == Types.DECIMAL || typeId == Types.SMALLINT
125: || typeId == Types.BIGINT || typeId == Types.TINYINT
126: || typeId == Types.NUMERIC || typeId == Types.REAL || typeId == Types.DOUBLE);
127: }
128:
129: /**
130: * Gets the display width of a column of a given type.
131: *
132: * @param dtd data type descriptor
133: *
134: * @return associated column display width
135: */
136: public static int getColumnDisplaySize(DataTypeDescriptor dtd) {
137: int typeId = dtd.getTypeId().getJDBCTypeId();
138: int storageLength = dtd.getMaximumWidth();
139: return DataTypeUtilities.getColumnDisplaySize(typeId,
140: storageLength);
141: }
142:
143: public static int getColumnDisplaySize(int typeId, int storageLength) {
144: int size;
145: switch (typeId) {
146: case Types.TIMESTAMP:
147: size = 26;
148: break;
149: case Types.DATE:
150: size = 10;
151: break;
152: case Types.TIME:
153: size = 8;
154: break;
155: case Types.INTEGER:
156: size = 11;
157: break;
158: case Types.SMALLINT:
159: size = 6;
160: break;
161: case Types.REAL:
162: case Types.FLOAT:
163: size = 13;
164: break;
165: case Types.DOUBLE:
166: size = 22;
167: break;
168: case Types.TINYINT:
169: size = 15;
170: break;
171:
172: case Types.BINARY:
173: case Types.VARBINARY:
174: case Types.LONGVARBINARY:
175: case Types.BLOB:
176: size = 2 * storageLength;
177: if (size < 0)
178: size = Integer.MAX_VALUE;
179: break;
180:
181: case Types.BIGINT:
182: size = 20;
183: break;
184: case Types.BIT:
185: case JDBC30Translation.SQL_TYPES_BOOLEAN:
186: // Types.BIT == SQL BOOLEAN, so 5 chars for 'false'
187: // In JDBC 3.0, Types.BIT or Types.BOOLEAN = SQL BOOLEAN
188: size = 5;
189: break;
190: default:
191: // MaximumWidth is -1 when it is unknown.
192: int w = storageLength;
193: size = (w > 0 ? w : 15);
194: break;
195: }
196: return size;
197: }
198:
199: /**
200: * Compute the maximum width (column display width) of a decimal or numeric data value,
201: * given its precision and scale.
202: *
203: * @param precision The precision (number of digits) of the data value.
204: * @param scale The number of fractional digits (digits to the right of the decimal point).
205: *
206: * @return The maximum number of chracters needed to display the value.
207: */
208: public static int computeMaxWidth(int precision, int scale) {
209: // There are 3 possible cases with respect to finding the correct max
210: // width for DECIMAL type.
211: // 1. If scale = 0, only sign should be added to precision.
212: // 2. scale=precision, 3 should be added to precision for sign, decimal and an additional char '0'.
213: // 3. precision > scale > 0, 2 should be added to precision for sign and decimal.
214: return (scale == 0) ? (precision + 1)
215: : ((scale == precision) ? (precision + 3)
216: : (precision + 2));
217: }
218: }
|