1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21 package org.apache.expreval.expr.function;
22
23 import org.apache.expreval.client.NullColumnValueException;
24 import org.apache.expreval.client.ResultMissingColumnException;
25 import org.apache.expreval.expr.literal.DateLiteral;
26 import org.apache.expreval.expr.node.DateValue;
27 import org.apache.expreval.expr.node.GenericValue;
28 import org.apache.hadoop.hbase.hbql.client.HBqlException;
29 import org.apache.hadoop.hbase.hbql.impl.HConnectionImpl;
30
31 import java.text.ParseException;
32 import java.text.SimpleDateFormat;
33 import java.util.List;
34
35 public class DateFunction extends GenericFunction implements DateValue {
36
37 public enum ConstantType {
38 NOW(0),
39 MINDATE(0),
40 MAXDATE(Long.MAX_VALUE);
41
42 final long value;
43
44 ConstantType(final long value) {
45 this.value = value;
46 }
47
48 public long getValue() {
49 return this.value;
50 }
51
52 public static GenericFunction getFunction(final String functionName) {
53
54 try {
55 final ConstantType type = ConstantType.valueOf(functionName.toUpperCase());
56 return new DateFunction(type);
57 }
58 catch (IllegalArgumentException e) {
59 return null;
60 }
61 }
62 }
63
64 public enum IntervalType {
65 MILLI(1),
66 SECOND(1000 * MILLI.getIntervalMillis()),
67 MINUTE(60 * SECOND.getIntervalMillis()),
68 HOUR(60 * MINUTE.getIntervalMillis()),
69 DAY(24 * HOUR.getIntervalMillis()),
70 WEEK(7 * DAY.getIntervalMillis()),
71 YEAR(52 * WEEK.getIntervalMillis());
72
73 private final long intervalMillis;
74
75 IntervalType(final long intervalMillis) {
76 this.intervalMillis = intervalMillis;
77 }
78
79 public long getIntervalMillis() {
80 return intervalMillis;
81 }
82
83 public static GenericFunction getFunction(final String functionName, final List<GenericValue> exprList) {
84
85 try {
86 final IntervalType type = IntervalType.valueOf(functionName.toUpperCase());
87 return new DateFunction(type, exprList);
88 }
89 catch (IllegalArgumentException e) {
90 return null;
91 }
92 }
93 }
94
95 private ConstantType constantType;
96 private IntervalType intervalType;
97 private DateLiteral dateValue;
98
99 public DateFunction(final FunctionType functionType, final List<GenericValue> exprs) {
100 super(functionType, exprs);
101 }
102
103 public DateFunction(final ConstantType constantType) {
104 super(FunctionType.DATECONSTANT, null);
105 this.constantType = constantType;
106 switch (this.getConstantType()) {
107 case NOW:
108 this.dateValue = new DateLiteral(DateLiteral.getNow());
109 break;
110 case MINDATE:
111 case MAXDATE:
112 this.dateValue = new DateLiteral(constantType.getValue());
113 break;
114 }
115 }
116
117 public DateFunction(final IntervalType intervalType, final List<GenericValue> exprs) {
118 super(FunctionType.DATEINTERVAL, exprs);
119 this.intervalType = intervalType;
120 }
121
122 private ConstantType getConstantType() {
123 return this.constantType;
124 }
125
126 private IntervalType getIntervalType() {
127 return this.intervalType;
128 }
129
130 public Long getValue(final HConnectionImpl conn, final Object object) throws HBqlException,
131 ResultMissingColumnException,
132 NullColumnValueException {
133 switch (this.getFunctionType()) {
134
135 case DATE: {
136 final String datestr = (String)this.getExprArg(0).getValue(conn, object);
137 final String pattern = (String)this.getExprArg(1).getValue(conn, object);
138 final SimpleDateFormat formatter = new SimpleDateFormat(pattern);
139
140 try {
141 return formatter.parse(datestr).getTime();
142 }
143 catch (ParseException e) {
144 throw new HBqlException(e.getMessage());
145 }
146 }
147
148 case DATEINTERVAL: {
149 final Number num = (Number)this.getExprArg(0).getValue(conn, object);
150 final long val = num.longValue();
151 return val * this.getIntervalType().getIntervalMillis();
152 }
153
154 case DATECONSTANT: {
155 return this.dateValue.getValue(conn, object);
156 }
157
158 case RANDOMDATE: {
159 return Math.abs(GenericFunction.randomVal.nextLong());
160 }
161
162 case LONGTODATE: {
163 final Number num = (Number)this.getExprArg(0).getValue(conn, object);
164 final long val = num.longValue();
165 this.dateValue = new DateLiteral(val);
166 return this.dateValue.getValue(conn, object);
167 }
168
169 default:
170 throw new HBqlException("Invalid function: " + this.getFunctionType());
171 }
172 }
173
174 protected String getFunctionName() {
175 if (this.isIntervalDate())
176 return this.getIntervalType().name();
177 else if (this.isConstantDate())
178 return this.getConstantType().name();
179 else
180 return super.getFunctionName();
181 }
182
183 public String asString() {
184 if (this.isIntervalDate())
185 return this.getIntervalType().name() + "(" + this.getExprArg(0).asString() + ")";
186 else if (this.isConstantDate())
187 return this.getConstantType().name() + "()";
188 else
189 return super.asString();
190 }
191 }