KickJava   Java API By Example, From Geeks To Geeks.

Java > Open Source Codes > org > apache > derby > iapi > types > SQLInteger


1 /*
2
3    Derby - Class org.apache.derby.iapi.types.SQLInteger
4
5    Licensed to the Apache Software Foundation (ASF) under one or more
6    contributor license agreements. See the NOTICE file distributed with
7    this work for additional information regarding copyright ownership.
8    The ASF licenses this file to you under the Apache License, Version 2.0
9    (the "License"); you may not use this file except in compliance with
10    the License. You may obtain a copy of the License at
11
12       http://www.apache.org/licenses/LICENSE-2.0
13
14    Unless required by applicable law or agreed to in writing, software
15    distributed under the License is distributed on an "AS IS" BASIS,
16    WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
17    See the License for the specific language governing permissions and
18    limitations under the License.
19
20  */

21
22 package org.apache.derby.iapi.types;
23
24 import org.apache.derby.iapi.services.io.ArrayInputStream;
25
26 import org.apache.derby.iapi.types.DataValueDescriptor;
27 import org.apache.derby.iapi.types.TypeId;
28 import org.apache.derby.iapi.types.NumberDataValue;
29 import org.apache.derby.iapi.types.BooleanDataValue;
30 import org.apache.derby.iapi.reference.SQLState;
31
32 import org.apache.derby.iapi.services.io.StoredFormatIds;
33 import org.apache.derby.iapi.services.io.Storable;
34
35 import org.apache.derby.iapi.error.StandardException;
36 import org.apache.derby.iapi.services.sanity.SanityManager;
37
38 import org.apache.derby.iapi.services.cache.ClassSize;
39
40 import org.apache.derby.iapi.types.NumberDataType;
41 import org.apache.derby.iapi.types.SQLBoolean;
42
43 import java.io.ObjectOutput JavaDoc;
44 import java.io.ObjectInput JavaDoc;
45 import java.io.IOException JavaDoc;
46
47 import java.sql.ResultSet JavaDoc;
48 import java.sql.PreparedStatement JavaDoc;
49 import java.sql.SQLException JavaDoc;
50
51 /**
52  * SQLInteger satisfies the DataValueDescriptor
53  * interfaces (i.e., OrderableDataType). It implements an integer column,
54  * e.g. for * storing a column value; it can be specified
55  * when constructed to not allow nulls. Nullability cannot be changed
56  * after construction, as it affects the storage size and mechanism.
57  * <p>
58  * Because OrderableDataType is a subtype of DataType,
59  * SQLInteger can play a role in either a DataType/Row
60  * or a OrderableDataType/Row, interchangeably.
61  * <p>
62  * We assume the store has a flag for nullness of the value,
63  * and simply return a 0-length array for the stored form
64  * when the value is null.
65  * <p>
66  * PERFORMANCE: There are likely alot of performance improvements
67  * possible for this implementation -- it new's Integer
68  * more than it probably wants to.
69  */

70 public final class SQLInteger
71     extends NumberDataType
72 {
73     /*
74      * DataValueDescriptor interface
75      * (mostly implemented in DataType)
76      */

77
78
79         // JDBC is lax in what it permits and what it
80
// returns, so we are similarly lax
81
// @see DataValueDescriptor
82
public int getInt()
83     {
84         /* This value is 0 if the SQLInteger is null */
85         return value;
86     }
87
88     /**
89      * @exception StandardException thrown on failure to convert
90      */

91     public byte getByte() throws StandardException
92     {
93         if (value > Byte.MAX_VALUE || value < Byte.MIN_VALUE)
94             throw StandardException.newException(SQLState.LANG_OUTSIDE_RANGE_FOR_DATATYPE, "TINYINT");
95         return (byte) value;
96     }
97
98     /**
99      * @exception StandardException thrown on failure to convert
100      */

101     public short getShort() throws StandardException
102     {
103         if (value > Short.MAX_VALUE || value < Short.MIN_VALUE)
104             throw StandardException.newException(SQLState.LANG_OUTSIDE_RANGE_FOR_DATATYPE, "SMALLINT");
105         return (short) value;
106     }
107
108     public long getLong()
109     {
110         return (long) value;
111     }
112
113     public float getFloat()
114     {
115         return (float) value;
116     }
117
118     public double getDouble()
119     {
120         return (double) value;
121     }
122
123     // for lack of a specification: 0 or null is false,
124
// all else is true
125
public boolean getBoolean()
126     {
127         return (value != 0);
128     }
129
130     public String JavaDoc getString()
131     {
132         if (isNull())
133             return null;
134         else
135             return Integer.toString(value);
136     }
137
138     public Object JavaDoc getObject()
139     {
140         if (isNull())
141             return null;
142         else
143             return new Integer JavaDoc(value);
144     }
145
146     public int getLength()
147     {
148         return INTEGER_LENGTH;
149     }
150
151     // this is for DataType's error generator
152
public String JavaDoc getTypeName()
153     {
154         return TypeId.INTEGER_NAME;
155     }
156
157     /*
158      * Storable interface, implies Externalizable, TypedFormat
159      */

160
161
162     /**
163         Return my format identifier.
164
165         @see org.apache.derby.iapi.services.io.TypedFormat#getTypeFormatId
166     */

167     public int getTypeFormatId() {
168         return StoredFormatIds.SQL_INTEGER_ID;
169     }
170
171     /*
172      * see if the integer value is null.
173      */

174     /** @see Storable#isNull */
175     public boolean isNull()
176     {
177         return isnull;
178     }
179
180     public void writeExternal(ObjectOutput JavaDoc out) throws IOException JavaDoc {
181
182         // never called when value is null
183
if (SanityManager.DEBUG)
184             SanityManager.ASSERT(! isNull());
185
186         out.writeInt(value);
187     }
188
189     /** @see java.io.Externalizable#readExternal */
190     public final void readExternal(ObjectInput JavaDoc in)
191         throws IOException JavaDoc {
192
193         value = in.readInt();
194         isnull = false;
195     }
196     public final void readExternalFromArray(ArrayInputStream in)
197         throws IOException JavaDoc {
198
199         value = in.readInt();
200         isnull = false;
201     }
202
203     /**
204      * @see Storable#restoreToNull
205      *
206      */

207
208     public void restoreToNull()
209     {
210         value = 0;
211         isnull = true;
212     }
213
214
215     /** @exception StandardException Thrown on error */
216     protected int typeCompare(DataValueDescriptor arg) throws StandardException
217     {
218         /* neither are null, get the value */
219
220         int thisValue = this.getInt();
221
222         int otherValue = arg.getInt();
223
224         if (thisValue == otherValue)
225             return 0;
226         else if (thisValue > otherValue)
227             return 1;
228         else
229             return -1;
230     }
231
232
233     /*
234      * DataValueDescriptor interface
235      */

236
237     /** @see DataValueDescriptor#getClone */
238     public DataValueDescriptor getClone()
239     {
240         SQLInteger nsi = new SQLInteger(value);
241
242         nsi.isnull = isnull;
243         return nsi;
244     }
245
246     /**
247      * @see DataValueDescriptor#getNewNull
248      */

249     public DataValueDescriptor getNewNull()
250     {
251         return new SQLInteger();
252     }
253
254     /**
255      * @see DataValueDescriptor#setValueFromResultSet
256      *
257      * @exception SQLException Thrown on error
258      */

259     public void setValueFromResultSet(ResultSet JavaDoc resultSet, int colNumber,
260                                       boolean isNullable)
261         throws SQLException JavaDoc
262     {
263             if ((value = resultSet.getInt(colNumber)) == 0)
264                 isnull = (isNullable && resultSet.wasNull());
265             else
266                 isnull = false;
267     }
268     /**
269         Set the value into a PreparedStatement.
270
271         @exception SQLException Error setting value in PreparedStatement
272     */

273     public final void setInto(PreparedStatement JavaDoc ps, int position) throws SQLException JavaDoc {
274
275         if (isNull()) {
276             ps.setNull(position, java.sql.Types.INTEGER);
277             return;
278         }
279
280         ps.setInt(position, value);
281     }
282     /**
283         Set this value into a ResultSet for a subsequent ResultSet.insertRow
284         or ResultSet.updateRow. This method will only be called for non-null values.
285
286         @exception SQLException thrown by the ResultSet object
287     */

288     public final void setInto(ResultSet JavaDoc rs, int position) throws SQLException JavaDoc {
289         rs.updateInt(position, value);
290     }
291
292     /*
293      * class interface
294      */

295
296     /*
297      * constructors
298      */

299
300     /** no-arg constructor, required by Formattable */
301     // This constructor also gets used when we are
302
// allocating space for an integer.
303
public SQLInteger()
304     {
305         isnull = true;
306     }
307
308     public SQLInteger(int val)
309     {
310         value = val;
311     }
312
313     public SQLInteger(char val)
314     {
315         value = val;
316     }
317
318     public SQLInteger(Integer JavaDoc obj) {
319         if (isnull = (obj == null))
320             ;
321         else
322             value = obj.intValue();
323     }
324
325     /**
326         @exception StandardException thrown if string not accepted
327      */

328     public void setValue(String JavaDoc theValue)
329         throws StandardException
330     {
331         if (theValue == null)
332         {
333             value = 0;
334             isnull = true;
335         }
336         else
337         {
338             try {
339                 value = Integer.valueOf(theValue.trim()).intValue();
340             } catch (NumberFormatException JavaDoc nfe) {
341                 throw invalidFormat();
342             }
343             isnull = false;
344         }
345     }
346
347     public void setValue(int theValue)
348     {
349         value = theValue;
350         isnull = false;
351     }
352
353     /**
354         @exception StandardException thrown on overflow
355      */

356     public void setValue(long theValue) throws StandardException
357     {
358         if (theValue > Integer.MAX_VALUE || theValue < Integer.MIN_VALUE) {
359             throw outOfRange();
360         }
361
362         value = (int)theValue;
363         isnull = false;
364     }
365
366     /**
367      * @see NumberDataValue#setValue
368      *
369      * @exception StandardException Thrown on error
370      */

371     public void setValue(float theValue) throws StandardException
372     {
373         theValue = NumberDataType.normalizeREAL(theValue);
374
375         if (theValue > Integer.MAX_VALUE || theValue < Integer.MIN_VALUE)
376             throw outOfRange();
377
378         float floorValue = (float)Math.floor(theValue);
379
380         value = (int)floorValue;
381         isnull = false;
382     }
383
384     /**
385      * @see NumberDataValue#setValue
386      *
387      * @exception StandardException Thrown on error
388      */

389     public void setValue(double theValue) throws StandardException
390     {
391         theValue = NumberDataType.normalizeDOUBLE(theValue);
392
393         if (theValue > Integer.MAX_VALUE || theValue < Integer.MIN_VALUE)
394             throw outOfRange();
395
396         double floorValue = Math.floor(theValue);
397
398         value = (int)floorValue;
399         isnull = false;
400     }
401
402     public void setValue(boolean theValue)
403     {
404         value = theValue?1:0;
405         isnull = false;
406     }
407
408     protected void setFrom(DataValueDescriptor theValue) throws StandardException {
409
410         setValue(theValue.getInt());
411     }
412
413     /*
414      * DataValueDescriptor interface
415      */

416
417     /** @see DataValueDescriptor#typePrecedence */
418     public int typePrecedence()
419     {
420         return TypeId.INT_PRECEDENCE;
421     }
422
423     /*
424     ** SQL Operators
425     */

426
427     /**
428      * The = operator as called from the language module, as opposed to
429      * the storage module.
430      *
431      * @param left The value on the left side of the =
432      * @param right The value on the right side of the =
433      *
434      * @return A SQL boolean value telling whether the two parameters are equal
435      *
436      * @exception StandardException Thrown on error
437      */

438
439     public BooleanDataValue equals(DataValueDescriptor left,
440                             DataValueDescriptor right)
441             throws StandardException
442     {
443         return SQLBoolean.truthValue(left,
444                                      right,
445                                      left.getInt() == right.getInt());
446     }
447
448     /**
449      * The <> operator as called from the language module, as opposed to
450      * the storage module.
451      *
452      * @param left The value on the left side of the <>
453      * @param right The value on the right side of the <>
454      *
455      * @return A SQL boolean value telling whether the two parameters
456      * are not equal
457      *
458      * @exception StandardException Thrown on error
459      */

460
461     public BooleanDataValue notEquals(DataValueDescriptor left,
462                             DataValueDescriptor right)
463             throws StandardException
464     {
465         return SQLBoolean.truthValue(left,
466                                      right,
467                                      left.getInt() != right.getInt());
468     }
469
470     /**
471      * The < operator as called from the language module, as opposed to
472      * the storage module.
473      *
474      * @param left The value on the left side of the <
475      * @param right The value on the right side of the <
476      *
477      * @return A SQL boolean value telling whether the first operand is less
478      * than the second operand
479      *
480      * @exception StandardException Thrown on error
481      */

482
483     public BooleanDataValue lessThan(DataValueDescriptor left,
484                             DataValueDescriptor right)
485             throws StandardException
486     {
487         return SQLBoolean.truthValue(left,
488                                      right,
489                                      left.getInt() < right.getInt());
490     }
491
492     /**
493      * The > operator as called from the language module, as opposed to
494      * the storage module.
495      *
496      * @param left The value on the left side of the >
497      * @param right The value on the right side of the >
498      *
499      * @return A SQL boolean value telling whether the first operand is greater
500      * than the second operand
501      *
502      * @exception StandardException Thrown on error
503      */

504
505     public BooleanDataValue greaterThan(DataValueDescriptor left,
506                             DataValueDescriptor right)
507             throws StandardException
508     {
509         return SQLBoolean.truthValue(left,
510                                      right,
511                                      left.getInt() > right.getInt());
512     }
513
514     /**
515      * The <= operator as called from the language module, as opposed to
516      * the storage module.
517      *
518      * @param left The value on the left side of the <=
519      * @param right The value on the right side of the <=
520      *
521      * @return A SQL boolean value telling whether the first operand is less
522      * than or equal to the second operand
523      *
524      * @exception StandardException Thrown on error
525      */

526
527     public BooleanDataValue lessOrEquals(DataValueDescriptor left,
528                             DataValueDescriptor right)
529             throws StandardException
530     {
531         return SQLBoolean.truthValue(left,
532                                      right,
533                                      left.getInt() <= right.getInt());
534     }
535
536     /**
537      * The >= operator as called from the language module, as opposed to
538      * the storage module.
539      *
540      * @param left The value on the left side of the >=
541      * @param right The value on the right side of the >=
542      *
543      * @return A SQL boolean value telling whether the first operand is greater
544      * than or equal to the second operand
545      *
546      * @exception StandardException Thrown on error
547      */

548
549     public BooleanDataValue greaterOrEquals(DataValueDescriptor left,
550                             DataValueDescriptor right)
551             throws StandardException
552     {
553         return SQLBoolean.truthValue(left,
554                                      right,
555                                      left.getInt() >= right.getInt());
556     }
557
558     /**
559      * This method implements the * operator for "int * int".
560      *
561      * @param left The first value to be multiplied
562      * @param right The second value to be multiplied
563      * @param result The result of a previous call to this method, null
564      * if not called yet
565      *
566      * @return A SQLInteger containing the result of the multiplication
567      *
568      * @exception StandardException Thrown on error
569      */

570
571     public NumberDataValue times(NumberDataValue left,
572                             NumberDataValue right,
573                             NumberDataValue result)
574                 throws StandardException
575     {
576         if (result == null)
577         {
578             result = new SQLInteger();
579         }
580
581         if (left.isNull() || right.isNull())
582         {
583             result.setToNull();
584             return result;
585         }
586
587         /*
588         ** Java does not check for overflow with integral types. We have to
589         ** check the result ourselves.
590         **
591         ** We can't use sign checking tricks like we do for '+' and '-' since
592         ** the product of 2 integers can wrap around multiple times. So, we
593         ** do long arithmetic and then verify that the result is within the
594         ** range of an int, throwing an error if it isn't.
595         */

596         long tempResult = left.getLong() * right.getLong();
597
598         result.setValue(tempResult);
599         return result;
600     }
601
602
603     /**
604         mod(int, int)
605     */

606     public NumberDataValue mod(NumberDataValue dividend,
607                                 NumberDataValue divisor,
608                                 NumberDataValue result)
609                                 throws StandardException {
610         if (result == null)
611         {
612             result = new SQLInteger();
613         }
614
615         if (dividend.isNull() || divisor.isNull())
616         {
617             result.setToNull();
618             return result;
619         }
620
621         /* Catch divide by 0 */
622         int intDivisor = divisor.getInt();
623         if (intDivisor == 0)
624         {
625             throw StandardException.newException(SQLState.LANG_DIVIDE_BY_ZERO);
626         }
627
628         result.setValue(dividend.getInt() % intDivisor);
629         return result;
630     }
631     /**
632      * This method implements the unary minus operator for int.
633      *
634      * @param result The result of a previous call to this method, null
635      * if not called yet
636      *
637      * @return A SQLInteger containing the result of the division
638      *
639      * @exception StandardException Thrown on error
640      */

641
642     public NumberDataValue minus(NumberDataValue result)
643                                     throws StandardException
644     {
645         int operandValue;
646
647         if (result == null)
648         {
649             result = new SQLInteger();
650         }
651
652         if (this.isNull())
653         {
654             result.setToNull();
655             return result;
656         }
657
658         operandValue = this.getInt();
659
660         /*
661         ** In two's complement arithmetic, the minimum value for a number
662         ** can't be negated, since there is no representation for its
663         ** positive value. For integers, the minimum value is -2147483648,
664         ** and the maximum value is 2147483647.
665         */

666         if (operandValue == Integer.MIN_VALUE)
667         {
668             throw outOfRange();
669         }
670
671         result.setValue(-operandValue);
672         return result;
673     }
674
675     /**
676      * This method implements the isNegative method.
677      *
678      * @return A boolean. If this.value is negative, return true.
679      * For positive values or null, return false.
680      */

681
682     protected boolean isNegative()
683     {
684         return !isNull() && value < 0;
685     }
686
687     /*
688      * String display of value
689      */

690
691     public String JavaDoc toString()
692     {
693         if (isNull())
694             return "NULL";
695         else
696             return Integer.toString(value);
697     }
698
699     /*
700      * Hash code
701      */

702     public int hashCode()
703     {
704         return value;
705     }
706
707     /*
708      * useful constants...
709      */

710     static final int INTEGER_LENGTH = 4; // must match the number of bytes written by DataOutput.writeInt()
711

712     private static final int BASE_MEMORY_USAGE = ClassSize.estimateBaseFromCatalog( SQLInteger.class);
713
714     public int estimateMemoryUsage()
715     {
716         return BASE_MEMORY_USAGE;
717     }
718
719     /*
720      * object state
721      */

722     private int value;
723     private boolean isnull;
724 }
725
Popular Tags