git-svn-id: https://svn.code.sf.net/p/jackcess/code/jackcess/branches/exprs@1166 f203690c-595d-4dc9-a70b-905162fa7fd2tags/jackcess-2.2.0
@@ -33,7 +33,7 @@ import static com.healthmarketscience.jackcess.impl.expr.DefaultFunctions.*; | |||
* | |||
* @author James Ahlborn | |||
*/ | |||
public class DefaultDateFunctions | |||
public class DefaultDateFunctions | |||
{ | |||
// min, valid, recognizable date: January 1, 100 A.D. 00:00:00 | |||
private static final double MIN_DATE = -657434.0d; | |||
@@ -46,7 +46,7 @@ public class DefaultDateFunctions | |||
private static final long SECONDS_PER_HOUR = 60L * 60L; | |||
private static final long SECONDS_PER_MINUTE = 60L; | |||
private static final long MILLIS_PER_SECOND = 1000L; | |||
private DefaultDateFunctions() {} | |||
static void init() { | |||
@@ -74,7 +74,7 @@ public class DefaultDateFunctions | |||
return BuiltinOperators.toValue(Value.Type.DATE, dd, fmt); | |||
} | |||
}); | |||
public static final Function NOW = registerFunc(new Func0("Now") { | |||
@Override | |||
protected Value eval0(EvalContext ctx) { | |||
@@ -104,7 +104,7 @@ public class DefaultDateFunctions | |||
return BuiltinOperators.toValue(Value.Type.TIME, dd, fmt); | |||
} | |||
}); | |||
public static final Function TIMER = registerFunc(new Func0("Timer") { | |||
@Override | |||
protected Value eval0(EvalContext ctx) { | |||
@@ -128,7 +128,7 @@ public class DefaultDateFunctions | |||
return BuiltinOperators.toValue(Value.Type.TIME, dd, fmt); | |||
} | |||
}); | |||
public static final Function HOUR = registerFunc(new Func1NullIsNull("Hour") { | |||
@Override | |||
protected Value eval1(EvalContext ctx, Value param1) { | |||
@@ -187,20 +187,21 @@ public class DefaultDateFunctions | |||
return null; | |||
} | |||
int day = nonNullToCalendarField(ctx, param1, Calendar.DAY_OF_WEEK); | |||
// FIXME handle first day of week | |||
// if(params.length > 1) { | |||
// int firstDay = params[1].getAsLong(); | |||
// } | |||
if(params.length > 1) { | |||
// TODO handle first day of week | |||
// int firstDay = params[1].getAsLong(); | |||
throw new UnsupportedOperationException(); | |||
} | |||
return BuiltinOperators.toValue(day); | |||
} | |||
}); | |||
private static int nonNullToCalendarField(EvalContext ctx, Value param, | |||
int field) { | |||
return nonNullToCalendar(ctx, param).get(field); | |||
} | |||
private static Calendar nonNullToCalendar(EvalContext ctx, Value param) { | |||
param = nonNullToDateValue(ctx, param); | |||
if(param == null) { | |||
@@ -212,7 +213,7 @@ public class DefaultDateFunctions | |||
cal.setTime(param.getAsDateTime(ctx)); | |||
return cal; | |||
} | |||
static Value nonNullToDateValue(EvalContext ctx, Value param) { | |||
Value.Type type = param.getType(); | |||
if(type.isTemporal()) { | |||
@@ -256,13 +257,13 @@ public class DefaultDateFunctions | |||
((BaseDateValue)param).getFormat() : | |||
BuiltinOperators.getDateFormatForType(ctx, param.getType())); | |||
} | |||
private static double dateOnly(double dd) { | |||
// the integral part of the date/time double is the date value. discard | |||
// the fractional portion | |||
return (long)dd; | |||
} | |||
private static double timeOnly(double dd) { | |||
// the fractional part of the date/time double is the time value. discard | |||
// the integral portion and convert to seconds |
@@ -28,7 +28,7 @@ import static com.healthmarketscience.jackcess.impl.expr.DefaultFunctions.*; | |||
* | |||
* @author James Ahlborn | |||
*/ | |||
public class DefaultTextFunctions | |||
public class DefaultTextFunctions | |||
{ | |||
private DefaultTextFunctions() {} | |||
@@ -36,7 +36,7 @@ public class DefaultTextFunctions | |||
static void init() { | |||
// dummy method to ensure this class is loaded | |||
} | |||
public static final Function ASC = registerFunc(new Func1("Asc") { | |||
@Override | |||
protected Value eval1(EvalContext ctx, Value param1) { | |||
@@ -44,7 +44,7 @@ public class DefaultTextFunctions | |||
int len = str.length(); | |||
if(len == 0) { | |||
throw new EvalException("No characters in string"); | |||
} | |||
} | |||
int lv = str.charAt(0); | |||
if((lv < 0) || (lv > 255)) { | |||
throw new EvalException("Character code '" + lv + | |||
@@ -61,7 +61,7 @@ public class DefaultTextFunctions | |||
int len = str.length(); | |||
if(len == 0) { | |||
throw new EvalException("No characters in string"); | |||
} | |||
} | |||
int lv = str.charAt(0); | |||
return BuiltinOperators.toValue(lv); | |||
} | |||
@@ -139,7 +139,7 @@ public class DefaultTextFunctions | |||
if(s1.regionMatches(ignoreCase, start, s2, 0, s2Len)) { | |||
// 1 based offsets | |||
return BuiltinOperators.toValue(start + 1); | |||
} | |||
} | |||
++start; | |||
} | |||
return BuiltinOperators.ZERO_VAL; | |||
@@ -173,7 +173,7 @@ public class DefaultTextFunctions | |||
start = params[2].getAsLongInt(); | |||
if(start == -1) { | |||
start = s1Len; | |||
} | |||
} | |||
// 1 based offsets | |||
--start; | |||
} | |||
@@ -181,12 +181,12 @@ public class DefaultTextFunctions | |||
if(params.length > 3) { | |||
ignoreCase = doIgnoreCase(params[3]); | |||
} | |||
start = Math.min(s1Len - s2Len, start); | |||
start = Math.min(s1Len - s2Len, start - s2Len + 1); | |||
while(start >= 0) { | |||
if(s1.regionMatches(ignoreCase, start, s2, 0, s2Len)) { | |||
// 1 based offsets | |||
return BuiltinOperators.toValue(start + 1); | |||
} | |||
} | |||
--start; | |||
} | |||
return BuiltinOperators.ZERO_VAL; | |||
@@ -306,7 +306,7 @@ public class DefaultTextFunctions | |||
if(params.length > 2) { | |||
ignoreCase = doIgnoreCase(params[2]); | |||
} | |||
int cmp = (ignoreCase ? | |||
int cmp = (ignoreCase ? | |||
s1.compareToIgnoreCase(s2) : s1.compareTo(s2)); | |||
return BuiltinOperators.toValue(cmp); | |||
} | |||
@@ -333,7 +333,7 @@ public class DefaultTextFunctions | |||
} | |||
}); | |||
private static String nchars(int num, char c) { | |||
StringBuilder sb = new StringBuilder(num); | |||
for(int i = 0; i < num; ++i) { | |||
@@ -350,7 +350,7 @@ public class DefaultTextFunctions | |||
while((start < end) && (str.charAt(start) == ' ')) { | |||
++start; | |||
} | |||
} | |||
} | |||
if(doRight) { | |||
while((start < end) && (str.charAt(end - 1) == ' ')) { | |||
--end; | |||
@@ -373,8 +373,8 @@ public class DefaultTextFunctions | |||
default: | |||
// vbDatabaseCompare -> unsupported | |||
throw new EvalException("Unsupported compare type " + cmpType); | |||
} | |||
} | |||
} | |||
} |
@@ -76,7 +76,31 @@ public class DefaultFunctionsTest extends TestCase | |||
assertEquals("9786", eval("=CStr(9786)")); | |||
assertEquals("-42", eval("=CStr(-42)")); | |||
// FIXME, instr, instrrev | |||
assertEquals(2, eval("=InStr('AFOOBAR', 'FOO')")); | |||
assertEquals(2, eval("=InStr('AFOOBAR', 'foo')")); | |||
assertEquals(2, eval("=InStr(1, 'AFOOBAR', 'foo')")); | |||
assertEquals(0, eval("=InStr(1, 'AFOOBAR', 'foo', 0)")); | |||
assertEquals(2, eval("=InStr(1, 'AFOOBAR', 'foo', 1)")); | |||
assertEquals(2, eval("=InStr(1, 'AFOOBAR', 'FOO', 0)")); | |||
assertEquals(2, eval("=InStr(2, 'AFOOBAR', 'FOO')")); | |||
assertEquals(0, eval("=InStr(3, 'AFOOBAR', 'FOO')")); | |||
assertEquals(0, eval("=InStr(17, 'AFOOBAR', 'FOO')")); | |||
assertEquals(2, eval("=InStr(1, 'AFOOBARFOOBAR', 'FOO')")); | |||
assertEquals(8, eval("=InStr(3, 'AFOOBARFOOBAR', 'FOO')")); | |||
assertNull(eval("=InStr(3, Null, 'FOO')")); | |||
assertEquals(2, eval("=InStrRev('AFOOBAR', 'FOO')")); | |||
assertEquals(2, eval("=InStrRev('AFOOBAR', 'foo')")); | |||
assertEquals(2, eval("=InStrRev('AFOOBAR', 'foo', -1)")); | |||
assertEquals(0, eval("=InStrRev('AFOOBAR', 'foo', -1, 0)")); | |||
assertEquals(2, eval("=InStrRev('AFOOBAR', 'foo', -1, 1)")); | |||
assertEquals(2, eval("=InStrRev('AFOOBAR', 'FOO', -1, 0)")); | |||
assertEquals(2, eval("=InStrRev('AFOOBAR', 'FOO', 4)")); | |||
assertEquals(0, eval("=InStrRev('AFOOBAR', 'FOO', 3)")); | |||
assertEquals(2, eval("=InStrRev('AFOOBAR', 'FOO', 17)")); | |||
assertEquals(2, eval("=InStrRev('AFOOBARFOOBAR', 'FOO', 9)")); | |||
assertEquals(8, eval("=InStrRev('AFOOBARFOOBAR', 'FOO', 10)")); | |||
assertNull(eval("=InStrRev(Null, 'FOO', 3)")); | |||
assertEquals("FOOO", eval("=UCase(\"fOoO\")")); | |||
assertEquals("fooo", eval("=LCase(\"fOoO\")")); |