KickJava   Java API By Example, From Geeks To Geeks.

Java > Open Source Codes > com > quadcap > sql > types > ValueInterval


1 package com.quadcap.sql.types;
2
3 /* Copyright 1999 - 2003 Quadcap Software. All rights reserved.
4  *
5  * This software is distributed under the Quadcap Free Software License.
6  * This software may be used or modified for any purpose, personal or
7  * commercial. Open Source redistributions are permitted. Commercial
8  * redistribution of larger works derived from, or works which bundle
9  * this software requires a "Commercial Redistribution License"; see
10  * http://www.quadcap.com/purchase.
11  *
12  * Redistributions qualify as "Open Source" under one of the following terms:
13  *
14  * Redistributions are made at no charge beyond the reasonable cost of
15  * materials and delivery.
16  *
17  * Redistributions are accompanied by a copy of the Source Code or by an
18  * irrevocable offer to provide a copy of the Source Code for up to three
19  * years at the cost of materials and delivery. Such redistributions
20  * must allow further use, modification, and redistribution of the Source
21  * Code under substantially the same terms as this license.
22  *
23  * Redistributions of source code must retain the copyright notices as they
24  * appear in each source code file, these license terms, and the
25  * disclaimer/limitation of liability set forth as paragraph 6 below.
26  *
27  * Redistributions in binary form must reproduce this Copyright Notice,
28  * these license terms, and the disclaimer/limitation of liability set
29  * forth as paragraph 6 below, in the documentation and/or other materials
30  * provided with the distribution.
31  *
32  * The Software is provided on an "AS IS" basis. No warranty is
33  * provided that the Software is free of defects, or fit for a
34  * particular purpose.
35  *
36  * Limitation of Liability. Quadcap Software shall not be liable
37  * for any damages suffered by the Licensee or any third party resulting
38  * from use of the Software.
39  */

40
41 import java.io.Externalizable JavaDoc;
42 import java.io.IOException JavaDoc;
43 import java.io.ObjectInput JavaDoc;
44 import java.io.ObjectOutput JavaDoc;
45
46 import java.util.Calendar JavaDoc;
47
48 import antlr.RecognitionException;
49
50 import com.quadcap.util.Debug;
51
52 /**
53  * An <b>INTERVAL</b> value.
54  *
55  * @author Stan Bailes
56  */

57 public class ValueInterval extends Value implements Externalizable JavaDoc {
58     long val;
59     boolean ym;
60     TypeInterval type;
61
62     public ValueInterval() {}
63
64     public ValueInterval(TypeInterval type, long val, boolean ym) {
65         this.type = type;
66     this.val = val;
67     this.ym = ym;
68     }
69     
70     public ValueInterval(String JavaDoc sval, int sign, TypeInterval type)
71     throws RecognitionException
72     {
73     this.type = type;
74         long v = 0;
75     int start = type.getStart();
76     ym = start == TypeInterval.YEAR || start == TypeInterval.MONTH;
77     long accum = 0;
78         int len = 0;
79         char c = 0;
80     for (int i = 0; i < sval.length(); i++) {
81         c = sval.charAt(i);
82         if (i == 0 && c == '-') sign = sign * -1;
83         else if (Character.isDigit(c)) {
84         accum *= 10;
85         accum += Character.digit(c, 10);
86                 len++;
87         } else if (c == ' ' || c == ':' || c == '-' || c == '.') {
88         v += sign * accum * type.units(start++, ym);
89         accum = 0;
90                 len = 0;
91         }
92     }
93
94         long xtra = 1;
95         if (c == '.') {
96             // assert type.end == ns
97
while (len < type.getSecPrecision()) {
98                 xtra *= 10;
99                 len++;
100             }
101         } else {
102             xtra = type.units(start, ym);
103         }
104         v += (sign * accum * xtra);
105         this.val = v;
106     }
107
108     public long getValue() { return val; }
109
110     public Calendar JavaDoc getCalendar() {
111     Calendar JavaDoc c = Calendar.getInstance();
112     for (int i = 0; i < Calendar.FIELD_COUNT - 1; i++) c.set(i, 0);
113     if (ym) {
114         c.add(Calendar.MONTH, (int)val);
115     } else {
116             long mult = type.getMult();
117             long v = val;
118             if (mult > 1000000) {
119                 v *= (mult / 1000000);
120             } else {
121                 v = (v * mult) / 1000000;
122             }
123         c.add(Calendar.MILLISECOND, (int)(v));
124     }
125     return c;
126     }
127
128     public Value getTimeComponent(int field) throws ValueException {
129         final int NANO = TypeInterval.NANO;
130         
131         Value ret = null;
132         int f = TypeInterval.convertCalendarField(field);
133         if (f < type.getStart() || f > type.getEnd()) {
134             ret = new ValueLong(0);
135         } else {
136             int e = type.getEnd();
137             int s = type.getStart();
138             if (e == s) {
139                 ret = new ValueLong(val);
140             } else if (f == e) {
141                 ret = new ValueLong(val % type.units(f-1, ym));
142             } else if (f == s) {
143                 ret = new ValueLong(val / type.units(s, ym));
144             } else {
145                 if (e != NANO) {
146                     ret = new ValueLong((val / type.units(f, ym)) %
147                                         type.units(f-1, ym));
148                 } else {
149                     ret = new ValueLong((val / type.units(f, ym)) %
150                                         type.units(f-1, ym));
151                 }
152             }
153         }
154         return ret;
155     }
156
157     public Value unop(int op) throws ValueException {
158     switch (op) {
159     case Op.NULL:
160         return ValueBoolean.falseBoolean;
161     case Op.PLUS:
162         return this;
163     case Op.MINUS:
164         return new ValueInterval(type, 0 - val, ym);
165     default:
166         throw new ValueException("Unary op: " + Op.toString(op) +
167                      " not implemented for this type");
168     }
169     }
170     
171     public Value binop(int op, Value l) throws ValueException {
172     return l.binop(op, this);
173     }
174
175     public Value binop(int op, ValueNull r) throws ValueException {
176     switch (op) {
177     case Op.EQ:
178     case Op.NE:
179     case Op.LT:
180     case Op.LE:
181     case Op.GT:
182     case Op.GE:
183     case Op.PLUS:
184     case Op.MINUS:
185         return ValueUnknown.valueUnknown;
186     case Op.COMPARE:
187         return r.valCmpNull();
188     default:
189         throw badBinop(op, r);
190     }
191     }
192
193     public Value binop(int op, ValueDouble r) throws ValueException {
194     switch (op) {
195     case Op.TIMES:
196         return new ValueInterval(type, (long)(val * r.doubleValue()), ym);
197     case Op.DIVIDE:
198         return new ValueInterval(type, (long)(val / r.doubleValue()), ym);
199     default:
200         throw badBinop(op, r);
201     }
202     }
203
204     public Value binop(int op, ValueFloat r) throws ValueException {
205     switch (op) {
206     case Op.TIMES:
207         return new ValueInterval(type, (long)(val * r.floatValue()), ym);
208     case Op.DIVIDE:
209         return new ValueInterval(type, (long)(val / r.floatValue()), ym);
210     default:
211         throw badBinop(op, r);
212     }
213     }
214
215     public Value binop(int op, ValueScaledInteger r) throws ValueException {
216     switch (op) {
217     case Op.TIMES:
218         return new ValueInterval(type, (long)(val * r.doubleValue()), ym);
219     case Op.DIVIDE:
220         return new ValueInterval(type, (long)(val / r.doubleValue()), ym);
221     default:
222         throw badBinop(op, r);
223     }
224     }
225
226     public Value binop(int op, ValueLong r) throws ValueException {
227     switch (op) {
228     case Op.TIMES:
229         return new ValueInterval(type, (long)(val * r.longValue()), ym);
230     case Op.DIVIDE:
231         return new ValueInterval(type, (long)(val / r.longValue()), ym);
232     default:
233         throw badBinop(op, r);
234     }
235     }
236
237     public Value binop(int op, ValueInteger r) throws ValueException {
238     switch (op) {
239     case Op.TIMES:
240         return new ValueInterval(type, (long)(val * r.intValue()), ym);
241     case Op.DIVIDE:
242         return new ValueInterval(type, (long)(val / r.intValue()), ym);
243     default:
244         throw badBinop(op, r);
245     }
246     }
247
248     public Value binop(int op, ValueShort r) throws ValueException {
249     switch (op) {
250     case Op.TIMES:
251         return new ValueInterval(type, (long)(val * r.shortValue()), ym);
252     case Op.DIVIDE:
253         return new ValueInterval(type, (long)(val / r.shortValue()), ym);
254     default:
255         throw badBinop(op, r);
256     }
257     }
258
259     public Value binop(int op, ValueByte r) throws ValueException {
260     switch (op) {
261     case Op.TIMES:
262         return new ValueInterval(type, (long)(val * r.byteValue()), ym);
263     case Op.DIVIDE:
264         return new ValueInterval(type, (long)(val / r.byteValue()), ym);
265     default:
266         throw badBinop(op, r);
267     }
268     }
269
270     public Value binop(int op, ValueInterval r) throws ValueException {
271     return ValueInterval.binop(op, this, r);
272     }
273
274     public static final Value binop(int op, ValueInterval e, ValueInterval f)
275     throws ValueException
276     {
277     if (e.ym != f.ym) {
278         throw new ValueException("Incompatible interval types: " +
279                      e.toString() + " vs " + f.toString());
280     }
281     switch (op) {
282         case Op.EQ:
283         return new ValueBoolean(e.val == f.val);
284         case Op.GE:
285         return new ValueBoolean(e.val >= f.val);
286         case Op.GT:
287         return new ValueBoolean(e.val > f.val);
288         case Op.LE:
289         return new ValueBoolean(e.val <= f.val);
290         case Op.LT:
291         return new ValueBoolean(e.val < f.val);
292         case Op.MINUS:
293         return new ValueInterval(e.type, e.val - f.val, e.ym);
294         case Op.NE:
295         return new ValueBoolean(e.val != f.val);
296         case Op.PLUS:
297         return new ValueInterval(e.type, e.val + f.val, e.ym);
298     case Op.COMPARE:
299         if (e.ym == f.ym) {
300         if (e.val < f.val) return ValueInteger.MINUS_ONE;
301         if (e.val > f.val) return ValueInteger.PLUS_ONE;
302         return ValueInteger.ZERO;
303         } else {
304         throw new ValueException("Can't compare year/month interval " +
305                      "to day-time interval");
306         }
307     default:
308         throw badBinop(op, e, f);
309     }
310     }
311
312     public void readExternal(ObjectInput JavaDoc in)
313     throws IOException JavaDoc, ClassNotFoundException JavaDoc
314     {
315     val = in.readLong();
316     type = (TypeInterval)in.readObject();
317     int start = type.getStart();
318     ym = start == TypeInterval.YEAR || start == TypeInterval.MONTH;
319     }
320     
321     public void writeExternal(ObjectOutput JavaDoc out)
322     throws IOException JavaDoc
323     {
324     out.writeLong(val);
325     out.writeObject(type);
326     }
327
328     public Object JavaDoc asJavaObject() {
329     return toString();
330     }
331
332     public void fromJavaObject(Object JavaDoc obj) throws ValueException {
333     throw new ValueException("bad type: " + obj);
334     }
335
336     public String JavaDoc toString() {
337     StringBuffer JavaDoc sb = new StringBuffer JavaDoc("INTERVAL ");
338     sb.append('\'');
339         if (type.getStart() == type.getEnd()) {
340             sb.append(String.valueOf(val / type.units(type.getStart(), ym)));
341         } else {
342             String JavaDoc delim = "";
343             for (int i = type.getStart(); i <= type.getEnd(); i++) {
344                 long t1 = (i == type.getStart()) ?
345                     val : val % type.units(i-1, ym);
346                 long t2 = t1 / type.units(i, ym);
347                 sb.append(delim);
348                 sb.append(Long.toString(t2));
349                 switch (i) {
350                 case TypeInterval.YEAR:
351                 case TypeInterval.MONTH:
352                     delim = "-"; break;
353                 case TypeInterval.DAY:
354                     delim = " "; break;
355                 case TypeInterval.HOUR:
356                 case TypeInterval.MINUTE:
357                     delim = ":"; break;
358                 case TypeInterval.SECOND:
359                     delim = "."; break;
360                 default:
361                 }
362             }
363         }
364     sb.append("' ");
365         sb.append(type.toString().substring(9));
366     return sb.toString();
367     }
368
369     public Value convert(TypeInterval newType) throws ValueException {
370         long m1 = type.getMult();
371         long m2 = newType.getMult();
372         long v = val;
373
374         if (m1 > m2) {
375             v *= (m1 / m2);
376         } else if (m1 < m2) {
377             v /= (m2 / m1);
378         }
379         Value ret = new ValueInterval(newType, v, ym);
380         return ret;
381     }
382
383     public Value convert(TypeDecimal t) {
384         int f = type.getStart();
385         return new ValueScaledInteger(val / type.units(f, ym));
386     }
387
388     public Type getType() {
389     return type;
390     }
391
392     public void serializeKey(KeyStream out) throws IOException JavaDoc {
393     out.writeBoolean(ym);
394     out.writeLong(val);
395     }
396
397 }
398
Popular Tags