diff options
author | James Ahlborn <jtahlborn@yahoo.com> | 2018-06-26 02:39:20 +0000 |
---|---|---|
committer | James Ahlborn <jtahlborn@yahoo.com> | 2018-06-26 02:39:20 +0000 |
commit | f495fcc761bcb275215f0d7d81b0135d8db56e2a (patch) | |
tree | 4500eb2ab3e081729910f18a047eefb7a47aa370 | |
parent | 2faf773bb91bccafcddd67c914bd5b38f5e99162 (diff) | |
download | jackcess-f495fcc761bcb275215f0d7d81b0135d8db56e2a.tar.gz jackcess-f495fcc761bcb275215f0d7d81b0135d8db56e2a.zip |
add some tests for functions; fix said functions
git-svn-id: https://svn.code.sf.net/p/jackcess/code/jackcess/branches/exprs@1166 f203690c-595d-4dc9-a70b-905162fa7fd2
3 files changed, 53 insertions, 28 deletions
diff --git a/src/main/java/com/healthmarketscience/jackcess/impl/expr/DefaultDateFunctions.java b/src/main/java/com/healthmarketscience/jackcess/impl/expr/DefaultDateFunctions.java index 0ef53e1..75fa68c 100644 --- a/src/main/java/com/healthmarketscience/jackcess/impl/expr/DefaultDateFunctions.java +++ b/src/main/java/com/healthmarketscience/jackcess/impl/expr/DefaultDateFunctions.java @@ -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 diff --git a/src/main/java/com/healthmarketscience/jackcess/impl/expr/DefaultTextFunctions.java b/src/main/java/com/healthmarketscience/jackcess/impl/expr/DefaultTextFunctions.java index 43bf0e3..b419f70 100644 --- a/src/main/java/com/healthmarketscience/jackcess/impl/expr/DefaultTextFunctions.java +++ b/src/main/java/com/healthmarketscience/jackcess/impl/expr/DefaultTextFunctions.java @@ -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); - } + } } - + } diff --git a/src/test/java/com/healthmarketscience/jackcess/impl/expr/DefaultFunctionsTest.java b/src/test/java/com/healthmarketscience/jackcess/impl/expr/DefaultFunctionsTest.java index 981c4d3..0b02888 100644 --- a/src/test/java/com/healthmarketscience/jackcess/impl/expr/DefaultFunctionsTest.java +++ b/src/test/java/com/healthmarketscience/jackcess/impl/expr/DefaultFunctionsTest.java @@ -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\")")); |