001: /*
002:
003: Derby - Class org.apache.derby.iapi.types.SQLBit
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.reference.SQLState;
025: import org.apache.derby.iapi.reference.Limits;
026:
027: import org.apache.derby.iapi.services.io.ArrayInputStream;
028:
029: import org.apache.derby.iapi.types.DataTypeDescriptor;
030: import org.apache.derby.iapi.types.DataValueDescriptor;
031: import org.apache.derby.iapi.types.TypeId;
032: import org.apache.derby.iapi.types.BitDataValue;
033: import org.apache.derby.iapi.types.DataValueDescriptor;
034: import org.apache.derby.iapi.types.ConcatableDataValue;
035: import org.apache.derby.iapi.types.VariableSizeDataValue;
036: import org.apache.derby.iapi.error.StandardException;
037:
038: import org.apache.derby.iapi.services.io.FormatIdUtil;
039: import org.apache.derby.iapi.services.io.StoredFormatIds;
040: import org.apache.derby.iapi.services.io.StreamStorable;
041: import org.apache.derby.iapi.services.io.FormatIdInputStream;
042:
043: import org.apache.derby.iapi.services.sanity.SanityManager;
044:
045: import org.apache.derby.iapi.types.BooleanDataValue;
046: import org.apache.derby.iapi.types.StringDataValue;
047: import org.apache.derby.iapi.types.NumberDataValue;
048:
049: import org.apache.derby.iapi.services.cache.ClassSize;
050: import org.apache.derby.iapi.util.StringUtil;
051:
052: import org.apache.derby.iapi.types.SQLInteger;
053:
054: import java.io.ObjectOutput;
055: import java.io.ObjectInput;
056: import java.io.IOException;
057: import java.io.InputStream;
058:
059: import java.sql.ResultSet;
060: import java.sql.SQLException;
061:
062: /**
063: * SQLBit represents the SQL type CHAR FOR BIT DATA
064: */
065: public class SQLBit extends SQLBinary {
066:
067: /**
068: *
069: * @exception StandardException Thrown on error
070: */
071: public Object getObject() throws StandardException {
072: return getBytes();
073: }
074:
075: public String getTypeName() {
076: return TypeId.BIT_NAME;
077: }
078:
079: /**
080: * Return max memory usage for a SQL Bit
081: */
082: int getMaxMemoryUsage() {
083: return Limits.DB2_CHAR_MAXWIDTH;
084: }
085:
086: /*
087: * Storable interface, implies Externalizable, TypedFormat
088: */
089:
090: /**
091: Return my format identifier.
092:
093: @see org.apache.derby.iapi.services.io.TypedFormat#getTypeFormatId
094: */
095: public int getTypeFormatId() {
096: return StoredFormatIds.SQL_BIT_ID;
097: }
098:
099: /** @see DataValueDescriptor#getNewNull */
100: public DataValueDescriptor getNewNull() {
101: return new SQLBit();
102: }
103:
104: /**
105: * Obtain the value using getBytes. This works for all FOR BIT DATA types.
106: * Getting a stream is problematic as any other getXXX() call on the ResultSet
107: * will close the stream we fetched. Therefore we have to create the value in-memory
108: * as a byte array.
109: * @see DataValueDescriptor#setValueFromResultSet
110: *
111: * @exception SQLException Thrown on error
112: */
113: public final void setValueFromResultSet(ResultSet resultSet,
114: int colNumber, boolean isNullable) throws SQLException {
115: setValue(resultSet.getBytes(colNumber));
116: }
117:
118: /*
119: * DataValueDescriptor interface
120: */
121:
122: /** @see DataValueDescriptor#typePrecedence */
123: public int typePrecedence() {
124: return TypeId.BIT_PRECEDENCE;
125: }
126:
127: /**
128: * Set the value from an non-null object.
129: */
130: final void setObject(Object theValue) throws StandardException {
131: setValue((byte[]) theValue);
132: }
133:
134: /*
135: * constructors
136: */
137:
138: /**
139: no-arg constructor, required by Formattable.
140: */
141: public SQLBit() {
142: }
143:
144: public SQLBit(byte[] val) {
145: dataValue = val;
146: }
147:
148: /**
149: * Normalization method - this method may be called when putting
150: * a value into a SQLBit, for example, when inserting into a SQLBit
151: * column. See NormalizeResultSet in execution.
152: *
153: * @param desiredType The type to normalize the source column to
154: * @param source The value to normalize
155: *
156: * @exception StandardException Thrown for null into
157: * non-nullable column, and for
158: * truncation error
159: */
160:
161: public void normalize(DataTypeDescriptor desiredType,
162: DataValueDescriptor source) throws StandardException {
163: int desiredWidth = desiredType.getMaximumWidth();
164:
165: ((SQLBinary) this ).setValue(source.getBytes());
166: setWidth(desiredWidth, 0, true);
167: }
168:
169: /**
170: * Set the width of the to the desired value. Used
171: * when CASTing. Ideally we'd recycle normalize(), but
172: * the behavior is different (we issue a warning instead
173: * of an error, and we aren't interested in nullability).
174: *
175: * @param desiredWidth the desired length
176: * @param desiredScale the desired scale (ignored)
177: * @param errorOnTrunc throw error on truncation
178: *
179: * @exception StandardException Thrown on non-zero truncation
180: * if errorOnTrunc is true
181: */
182: public void setWidth(int desiredWidth, int desiredScale, // Ignored
183: boolean errorOnTrunc) throws StandardException {
184: /*
185: ** If the input is NULL, nothing to do.
186: */
187: if (getValue() == null) {
188: return;
189: }
190:
191: int sourceWidth = dataValue.length;
192:
193: /*
194: ** If the input is shorter than the desired type,
195: ** then pad with blanks to the right length.
196: */
197: if (sourceWidth < desiredWidth) {
198: byte[] actualData = new byte[desiredWidth];
199: System.arraycopy(dataValue, 0, actualData, 0,
200: dataValue.length);
201: java.util.Arrays.fill(actualData, dataValue.length,
202: actualData.length, SQLBinary.PAD);
203: dataValue = actualData;
204: }
205: /*
206: ** Truncation?
207: */
208: else if (sourceWidth > desiredWidth) {
209: if (errorOnTrunc) {
210: // error if truncating non pad characters.
211: for (int i = desiredWidth; i < dataValue.length; i++) {
212:
213: if (dataValue[i] != SQLBinary.PAD)
214: throw StandardException.newException(
215: SQLState.LANG_STRING_TRUNCATION,
216: getTypeName(),
217: StringUtil.formatForPrint(this
218: .toString()), String
219: .valueOf(desiredWidth));
220: }
221: }
222: //else
223: //{
224: // RESOLVE: when we have warnings, issue a warning if
225: // truncation of non-zero bits will occur
226: //}
227:
228: /*
229: ** Truncate to the desired width.
230: */
231: byte[] shrunkData = new byte[desiredWidth];
232: System.arraycopy(dataValue, 0, shrunkData, 0, desiredWidth);
233: dataValue = shrunkData;
234:
235: }
236: }
237:
238: }
|