001: /*
002: * $Id: TestDateAddFunction.java,v 1.7 2005/03/04 09:09:17 ahimanikya Exp $
003: * =======================================================================
004: * Copyright (c) 2004 Axion Development Team. All rights reserved.
005: *
006: * Redistribution and use in source and binary forms, with or without
007: * modification, are permitted provided that the following conditions
008: * are met:
009: *
010: * 1. Redistributions of source code must retain the above
011: * copyright notice, this list of conditions and the following
012: * disclaimer.
013: *
014: * 2. Redistributions in binary form must reproduce the above copyright
015: * notice, this list of conditions and the following disclaimer in
016: * the documentation and/or other materials provided with the
017: * distribution.
018: *
019: * 3. The names "Tigris", "Axion", nor the names of its contributors may
020: * not be used to endorse or promote products derived from this
021: * software without specific prior written permission.
022: *
023: * 4. Products derived from this software may not be called "Axion", nor
024: * may "Tigris" or "Axion" appear in their names without specific prior
025: * written permission.
026: *
027: * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
028: * "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT
029: * LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A
030: * PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT
031: * OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL,
032: * SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT
033: * LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE,
034: * DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY
035: * THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
036: * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE
037: * OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
038: * =======================================================================
039: */
040:
041: package org.axiondb.functions;
042:
043: import java.sql.Date;
044: import java.sql.Time;
045: import java.sql.Timestamp;
046: import java.util.Calendar;
047: import java.util.HashMap;
048: import java.util.Map;
049:
050: import org.axiondb.ColumnIdentifier;
051: import org.axiondb.RowDecorator;
052: import org.axiondb.engine.rows.SimpleRow;
053: import org.axiondb.types.DateType;
054: import org.axiondb.types.TimestampType;
055:
056: import junit.framework.Test;
057: import junit.framework.TestSuite;
058:
059: /**
060: * @author radval To change the template for this generated type comment go to Window -
061: * Preferences - Java - Code Generation - Code and Comments
062: */
063: public class TestDateAddFunction extends BaseFunctionTest {
064:
065: public TestDateAddFunction(String testName) {
066: super (testName);
067: }
068:
069: public void setUp() throws Exception {
070: super .setUp();
071: TimestampType.setTimeZone("GMT");
072: }
073:
074: /*
075: * (non-Javadoc)
076: *
077: * @see org.axiondb.functions.BaseFunctionTest#makeFunction()
078: */
079: protected ConcreteFunction makeFunction() {
080: return new DateAddFunction();
081: }
082:
083: public static Test suite() {
084: TestSuite suite = new TestSuite(TestDateAddFunction.class);
085: return suite;
086: }
087:
088: public void testAddYearsToDate() throws Exception {
089: DateAddFunction function = new DateAddFunction();
090: ColumnIdentifier intervalType = new ColumnIdentifier(
091: "intervalType");
092: ColumnIdentifier interval = new ColumnIdentifier("interval");
093: ColumnIdentifier timestamp = new ColumnIdentifier("timestamp");
094:
095: function.addArgument(intervalType);
096: function.addArgument(interval);
097: function.addArgument(timestamp);
098:
099: Map map = new HashMap();
100: map.put(intervalType, new Integer(0));
101: map.put(interval, new Integer(1));
102: map.put(timestamp, new Integer(2));
103:
104: //April 01 2004 GMT
105: Timestamp input = new Timestamp(34 * 365 * 24 * 60 * 60 * 1000L
106: + //year
107: 9 * 24 * 60 * 60 * 1000L + // leap years '72,'76,'80,'84,'88,'92,'96, 2000,
108: // 2004
109: (31 + 28 + 31 + 01) * 24 * 60 * 60 * 1000L // April 01
110: );
111:
112: //April 01 2005 GMT
113: Timestamp result = new Timestamp(35 * 365 * 24 * 60 * 60
114: * 1000L + //year
115: 9 * 24 * 60 * 60 * 1000L + // leap years '72,'76,'80,'84,'88,'92,'96, 2000,
116: // 2004
117: (31 + 28 + 31 + 01) * 24 * 60 * 60 * 1000L // April 01
118: );
119:
120: RowDecorator dec = new RowDecorator(map);
121: dec.setRow(new SimpleRow(new Object[] { "YEAR", new Integer(1),
122: input }));
123:
124: assertEquals(result, function.evaluate(dec));
125: }
126:
127: public void testAddQuartersToDate() throws Exception {
128: DateAddFunction function = new DateAddFunction();
129: ColumnIdentifier intervalType = new ColumnIdentifier(
130: "intervalType");
131: ColumnIdentifier interval = new ColumnIdentifier("interval");
132: ColumnIdentifier timestamp = new ColumnIdentifier("timestamp");
133:
134: function.addArgument(intervalType);
135: function.addArgument(interval);
136: function.addArgument(timestamp);
137:
138: Map map = new HashMap();
139: map.put(intervalType, new Integer(0));
140: map.put(interval, new Integer(1));
141: map.put(timestamp, new Integer(2));
142:
143: //Feb 29 1960 GMT
144: Timestamp input = new Timestamp(-1
145: * (10 * 365 * 24 * 60 * 60 * 1000L + //year
146: 3 * 24 * 60 * 60 * 1000L + // leap years '60,'64,'68
147: (31 + 29) * 24 * 60 * 60 * 1000L) // Feb 29
148: );
149:
150: Calendar c = Calendar.getInstance(TimestampType.getTimeZone());
151: c.setTimeInMillis(input.getTime());
152: c.add(Calendar.MONTH, 75 * 3);
153:
154: Timestamp result = new Timestamp(c.getTimeInMillis());
155:
156: RowDecorator dec = new RowDecorator(map);
157: dec.setRow(new SimpleRow(new Object[] { "QUARTER",
158: new Integer(75), input }));
159:
160: assertEquals(result, function.evaluate(dec));
161: }
162:
163: public void testAddMonthsToDate() throws Exception {
164: DateAddFunction function = new DateAddFunction();
165: ColumnIdentifier intervalType = new ColumnIdentifier(
166: "intervalType");
167: ColumnIdentifier interval = new ColumnIdentifier("interval");
168: ColumnIdentifier timestamp = new ColumnIdentifier("timestamp");
169:
170: function.addArgument(intervalType);
171: function.addArgument(interval);
172: function.addArgument(timestamp);
173:
174: Map map = new HashMap();
175: map.put(intervalType, new Integer(0));
176: map.put(interval, new Integer(1));
177: map.put(timestamp, new Integer(2));
178:
179: //Feb 01 1980 GMT
180: Timestamp input = new Timestamp(10 * 365 * 24 * 60 * 60 * 1000L
181: + //year
182: 3 * 24 * 60 * 60 * 1000L + // leap years '72,'76,'80
183: (31 + 01) * 24 * 60 * 60 * 1000L // Feb 01
184: );
185:
186: Calendar c = Calendar.getInstance(TimestampType.getTimeZone());
187: c.setTimeInMillis(input.getTime());
188: c.add(Calendar.MONTH, 125);
189: //1990-07-01
190: Timestamp result = new Timestamp(c.getTimeInMillis());
191:
192: RowDecorator dec = new RowDecorator(map);
193: dec.setRow(new SimpleRow(new Object[] { "MONTH",
194: new Integer(125), input }));
195: assertEquals(result, function.evaluate(dec));
196: }
197:
198: public void testAddDaysToDate() throws Exception {
199: DateAddFunction function = new DateAddFunction();
200: ColumnIdentifier intervalType = new ColumnIdentifier(
201: "intervalType");
202: ColumnIdentifier interval = new ColumnIdentifier("interval");
203: ColumnIdentifier timestamp = new ColumnIdentifier("timestamp");
204:
205: function.addArgument(intervalType);
206: function.addArgument(interval);
207: function.addArgument(timestamp);
208:
209: Map map = new HashMap();
210: map.put(intervalType, new Integer(0));
211: map.put(interval, new Integer(1));
212: map.put(timestamp, new Integer(2));
213:
214: //Feb 29 1980 GMT
215: Timestamp input = new Timestamp(10 * 365 * 24 * 60 * 60 * 1000L
216: + //year
217: 3 * 24 * 60 * 60 * 1000L + // leap years '72,'76,'80
218: (31 + 29) * 24 * 60 * 60 * 1000L // Feb 29
219: );
220:
221: Calendar c = Calendar.getInstance(TimestampType.getTimeZone());
222: c.setTimeInMillis(input.getTime());
223: c.add(Calendar.DAY_OF_YEAR, 377);
224: //1981-03-12
225: Timestamp result = new Timestamp(c.getTimeInMillis());
226:
227: RowDecorator dec = new RowDecorator(map);
228: dec.setRow(new SimpleRow(new Object[] { "DAY",
229: new Integer(377), input }));
230:
231: assertEquals(result, function.evaluate(dec));
232: }
233:
234: public void testAddHoursToDate() throws Exception {
235: DateAddFunction function = new DateAddFunction();
236: ColumnIdentifier intervalType = new ColumnIdentifier(
237: "intervalType");
238: ColumnIdentifier interval = new ColumnIdentifier("interval");
239: ColumnIdentifier timestamp = new ColumnIdentifier("timestamp");
240:
241: function.addArgument(intervalType);
242: function.addArgument(interval);
243: function.addArgument(timestamp);
244:
245: Map map = new HashMap();
246: map.put(intervalType, new Integer(0));
247: map.put(interval, new Integer(1));
248: map.put(timestamp, new Integer(2));
249:
250: //April 29 1999 11:20:33 GMT
251: Timestamp input = new Timestamp(29 * 365 * 24 * 60 * 60 * 1000L
252: + //year
253: 7 * 24 * 60 * 60 * 1000L + // leap years '72,'76,'80,84,88,92,96
254: (31 + 28 + 31 + 29) * 24 * 60 * 60 * 1000L + // Feb 29
255: 11 * 60 * 60 * 1000L + //Hours
256: 20 * 60 * 1000L + //minutes
257: 33 * 1000L //seconds
258: );
259:
260: Calendar c = Calendar.getInstance(TimestampType.getTimeZone());
261: c.setTimeInMillis(input.getTime());
262: c.add(Calendar.HOUR_OF_DAY, 160);
263:
264: //1999-05-06 03:20:33.0
265: Timestamp result = new Timestamp(c.getTimeInMillis());
266:
267: RowDecorator dec = new RowDecorator(map);
268: dec.setRow(new SimpleRow(new Object[] { "HOUR",
269: new Integer(160), input }));
270: assertEquals(result, function.evaluate(dec));
271: }
272:
273: public void testAddMinutesToDate() throws Exception {
274: DateAddFunction function = new DateAddFunction();
275: ColumnIdentifier intervalType = new ColumnIdentifier(
276: "intervalType");
277: ColumnIdentifier interval = new ColumnIdentifier("interval");
278: ColumnIdentifier timestamp = new ColumnIdentifier("timestamp");
279:
280: function.addArgument(intervalType);
281: function.addArgument(interval);
282: function.addArgument(timestamp);
283:
284: Map map = new HashMap();
285: map.put(intervalType, new Integer(0));
286: map.put(interval, new Integer(1));
287: map.put(timestamp, new Integer(2));
288:
289: //Nov 30 2001 18:56:49 GMT
290: Timestamp input = new Timestamp(31 * 365 * 24 * 60 * 60
291: * 1000L
292: + //year
293: 8 * 24 * 60 * 60 * 1000L
294: + // leap years '72,'76,'80,84,88,92,96,2000
295: (31 + 28 + 31 + 30 + 31 + 30 + 31 + 31 + 30 + 31 + 30)
296: * 24 * 60 * 60 * 1000L + // Nov
297: // 30
298: 18 * 60 * 60 * 1000L + //Hours
299: 56 * 60 * 1000L + //minutes
300: 49 * 1000L //seconds
301: );
302:
303: Calendar c = Calendar.getInstance(TimestampType.getTimeZone());
304: c.setTimeInMillis(input.getTime());
305: c.add(Calendar.MINUTE, 2089);
306:
307: //2001-12-02 05:45:49.0
308: Timestamp result = new Timestamp(c.getTimeInMillis());
309:
310: RowDecorator dec = new RowDecorator(map);
311: dec.setRow(new SimpleRow(new Object[] { "MINUTE",
312: new Integer(2089), input }));
313: assertEquals(result, function.evaluate(dec));
314: }
315:
316: public void testAddSecondsToDate() throws Exception {
317: DateAddFunction function = new DateAddFunction();
318: ColumnIdentifier intervalType = new ColumnIdentifier(
319: "intervalType");
320: ColumnIdentifier interval = new ColumnIdentifier("interval");
321: ColumnIdentifier timestamp = new ColumnIdentifier("timestamp");
322:
323: function.addArgument(intervalType);
324: function.addArgument(interval);
325: function.addArgument(timestamp);
326:
327: Map map = new HashMap();
328: map.put(intervalType, new Integer(0));
329: map.put(interval, new Integer(1));
330: map.put(timestamp, new Integer(2));
331:
332: //Dec 30 2000 21:56:49 GMT
333: Timestamp input = new Timestamp(
334: 30 * 365 * 24
335: * 60
336: * 60
337: * 1000L
338: + //year
339: 8
340: * 24
341: * 60
342: * 60
343: * 1000L
344: + // leap years '72,'76,'80,84,88,92,96,2000
345: (31 + 28 + 31 + 30 + 31 + 30 + 31 + 31 + 30
346: + 31 + 30 + 30) * 24 * 60 * 60 * 1000L + // Dec
347: // 30
348: 21 * 60 * 60 * 1000L + //Hours
349: 56 * 60 * 1000L + //minutes
350: 49 * 1000L //seconds
351: );
352:
353: Calendar c = Calendar.getInstance(TimestampType.getTimeZone());
354: c.setTimeInMillis(input.getTime());
355: c.add(Calendar.SECOND, 9999);
356:
357: //2000-12-31 00:43:28.0
358: Timestamp result = new Timestamp(c.getTimeInMillis());
359:
360: RowDecorator dec = new RowDecorator(map);
361: dec.setRow(new SimpleRow(new Object[] { "SECOND",
362: new Integer(9999), input }));
363: assertEquals(result, function.evaluate(dec));
364: }
365:
366: public void testAddMilliSecondsToDate() throws Exception {
367: DateAddFunction function = new DateAddFunction();
368: ColumnIdentifier intervalType = new ColumnIdentifier(
369: "intervalType");
370: ColumnIdentifier interval = new ColumnIdentifier("interval");
371: ColumnIdentifier timestamp = new ColumnIdentifier("timestamp");
372:
373: function.addArgument(intervalType);
374: function.addArgument(interval);
375: function.addArgument(timestamp);
376:
377: Map map = new HashMap();
378: map.put(intervalType, new Integer(0));
379: map.put(interval, new Integer(1));
380: map.put(timestamp, new Integer(2));
381:
382: //Dec 31 2000 23:56:49 GMT
383: Timestamp input = new Timestamp(
384: 30 * 365 * 24
385: * 60
386: * 60
387: * 1000L
388: + //year
389: 8
390: * 24
391: * 60
392: * 60
393: * 1000L
394: + // leap years '72,'76,'80,84,88,92,96,2000
395: (31 + 28 + 31 + 30 + 31 + 30 + 31 + 31 + 30
396: + 31 + 30 + 31) * 24 * 60 * 60 * 1000L + // Dec
397: // 30
398: 23 * 60 * 60 * 1000L + //Hours
399: 56 * 60 * 1000L + //minutes
400: 49 * 1000L //seconds
401: );
402:
403: Calendar c = Calendar.getInstance(TimestampType.getTimeZone());
404: c.setTimeInMillis(input.getTime());
405: c.add(Calendar.MILLISECOND, 198774);
406:
407: //2001-01-01 00:00:07.774
408: Timestamp result = new Timestamp(c.getTimeInMillis());
409:
410: RowDecorator dec = new RowDecorator(map);
411: dec.setRow(new SimpleRow(new Object[] { "MILLISECOND",
412: new Integer(198774), input }));
413: assertEquals(result, function.evaluate(dec));
414: }
415:
416: public void testNullIntervalInputYieldsNull() {
417: DateAddFunction function = new DateAddFunction();
418: ColumnIdentifier intervalType = new ColumnIdentifier(
419: "intervalType");
420: ColumnIdentifier interval = new ColumnIdentifier("interval");
421: ColumnIdentifier timestamp = new ColumnIdentifier("timestamp");
422:
423: function.addArgument(intervalType);
424: function.addArgument(interval);
425: function.addArgument(timestamp);
426:
427: HashMap map = new HashMap();
428: map.put(intervalType, new Integer(0));
429: map.put(interval, new Integer(1));
430: map.put(timestamp, new Integer(2));
431:
432: RowDecorator dec = new RowDecorator(map);
433: dec.setRow(new SimpleRow(new Object[] { "DAY", null,
434: new Timestamp(System.currentTimeMillis()) }));
435: try {
436: assertNull(
437: "Expected null return for DateAdd with null for interval input.",
438: function.evaluate(dec));
439: } catch (Exception e) {
440: fail("Null for interval input of DateAdd should not have thrown an Exception: "
441: + e);
442: }
443: }
444:
445: public void testDateTypeInput() throws Exception {
446: final int INCR = 5;
447:
448: DateAddFunction function = new DateAddFunction();
449: ColumnIdentifier intervalType = new ColumnIdentifier(
450: "intervalType");
451: ColumnIdentifier interval = new ColumnIdentifier("interval");
452: ColumnIdentifier date = new ColumnIdentifier("date");
453:
454: function.addArgument(intervalType);
455: function.addArgument(interval);
456: function.addArgument(date);
457:
458: HashMap map = new HashMap();
459: map.put(intervalType, new Integer(0));
460: map.put(interval, new Integer(1));
461: map.put(date, new Integer(2));
462:
463: Date input = new Date(DateType.normalizeToUTCZeroHour(System
464: .currentTimeMillis()));
465: Calendar c = Calendar.getInstance(TimestampType.getTimeZone());
466: c.setTimeInMillis(input.getTime());
467: c.add(Calendar.DATE, INCR);
468: Timestamp result = new Timestamp(c.getTimeInMillis());
469:
470: RowDecorator dec = new RowDecorator(map);
471: dec.setRow(new SimpleRow(new Object[] { "DAY",
472: new Integer(INCR), input }));
473: assertEquals("DateAdd failed for DATE input - ", result,
474: function.evaluate(dec));
475: }
476:
477: public void testTimeTypeInput() throws Exception {
478: final int INCR = 2;
479:
480: DateAddFunction function = new DateAddFunction();
481: ColumnIdentifier intervalType = new ColumnIdentifier(
482: "intervalType");
483: ColumnIdentifier interval = new ColumnIdentifier("interval");
484: ColumnIdentifier time = new ColumnIdentifier("time");
485:
486: function.addArgument(intervalType);
487: function.addArgument(interval);
488: function.addArgument(time);
489:
490: HashMap map = new HashMap();
491: map.put(intervalType, new Integer(0));
492: map.put(interval, new Integer(1));
493: map.put(time, new Integer(2));
494:
495: Time input = new Time(0L);
496: Calendar c = Calendar.getInstance(TimestampType.getTimeZone());
497: c.setTimeInMillis(input.getTime());
498: c.add(Calendar.DATE, INCR);
499: Timestamp result = new Timestamp(c.getTimeInMillis());
500:
501: RowDecorator dec = new RowDecorator(map);
502: dec.setRow(new SimpleRow(new Object[] { "DAY",
503: new Integer(INCR), input }));
504: assertEquals("DateAdd failed for TIME input - ", result,
505: function.evaluate(dec));
506: }
507:
508: public void testNullTimestampInputYieldsNull() {
509: DateAddFunction function = new DateAddFunction();
510: ColumnIdentifier intervalType = new ColumnIdentifier(
511: "intervalType");
512: ColumnIdentifier interval = new ColumnIdentifier("interval");
513: ColumnIdentifier timestamp = new ColumnIdentifier("timestamp");
514:
515: function.addArgument(intervalType);
516: function.addArgument(interval);
517: function.addArgument(timestamp);
518:
519: HashMap map = new HashMap();
520: map.put(intervalType, new Integer(0));
521: map.put(interval, new Integer(1));
522: map.put(timestamp, new Integer(2));
523:
524: RowDecorator dec = new RowDecorator(map);
525: dec.setRow(new SimpleRow(new Object[] { "DAY", new Integer(1),
526: null }));
527: try {
528: assertNull(
529: "Expected null return for DateAdd with null for timestamp input.",
530: function.evaluate(dec));
531: } catch (Exception e) {
532: fail("Null for timestamp input of DateAdd should not have thrown an Exception: "
533: + e);
534: }
535: }
536:
537: public void testInvalidArguments() {
538: DateAddFunction function = new DateAddFunction();
539: ColumnIdentifier intervalType = new ColumnIdentifier(
540: "intervalType");
541: ColumnIdentifier interval = new ColumnIdentifier("interval");
542: ColumnIdentifier timestamp = new ColumnIdentifier("timestamp");
543:
544: function.addArgument(intervalType);
545: function.addArgument(interval);
546: function.addArgument(timestamp);
547:
548: HashMap map = new HashMap();
549: map.put(intervalType, new Integer(0));
550: map.put(interval, new Integer(1));
551: map.put(timestamp, new Integer(2));
552:
553: RowDecorator dec = new RowDecorator(map);
554: Date input = new Date(DateType.normalizeToUTCZeroHour(System
555: .currentTimeMillis()));
556: dec.setRow(new SimpleRow(
557: new Object[] { "DAY", "integer", input }));
558: try {
559: function.evaluate(dec);
560: fail("Expected conversion error");
561: } catch (Exception e) {
562: // Expected
563: }
564:
565: dec.setRow(new SimpleRow(new Object[] { "DAY", new Integer(1),
566: "input" }));
567: try {
568: function.evaluate(dec);
569: fail("Expected conversion error");
570: } catch (Exception e) {
571: // Expected
572: }
573:
574: dec.setRow(new SimpleRow(new Object[] { "DAY", new Integer(1),
575: new Object[] { "input" } }));
576: try {
577: function.evaluate(dec);
578: fail("Expected conversion error");
579: } catch (Exception e) {
580: // Expected
581: }
582:
583: }
584:
585: public void testMakeNewInstance() {
586: DateAddFunction function = new DateAddFunction();
587: assertTrue(function.makeNewInstance() instanceof DateAddFunction);
588: assertTrue(function.makeNewInstance() != function
589: .makeNewInstance());
590: }
591:
592: public void testInvalid() throws Exception {
593: DateAddFunction function = new DateAddFunction();
594: assertTrue(!function.isValid());
595: }
596:
597: public void testValid() throws Exception {
598: DateAddFunction function = new DateAddFunction();
599: function.addArgument(new ColumnIdentifier("interval"));
600: function.addArgument(new ColumnIdentifier("intervalType"));
601: function.addArgument(new ColumnIdentifier("timestamp"));
602: assertTrue(function.isValid());
603: }
604: }
|