git-svn-id: https://svn.code.sf.net/p/jackcess/code/jackcess/trunk@1215 f203690c-595d-4dc9-a70b-905162fa7fd2tags/jackcess-2.2.1
@@ -225,7 +225,7 @@ limitations under the License. | |||
* <tr class="TableRowColor"><td>RTrim[$]</td><td>Y</td></tr> | |||
* <tr class="TableRowColor"><td>Trim[$]</td><td>Y</td></tr> | |||
* <tr class="TableRowColor"><td>Mid[$]</td><td>Y</td></tr> | |||
* <tr class="TableRowColor"><td>Replace</td><td></td></tr> | |||
* <tr class="TableRowColor"><td>Replace</td><td>Y</td></tr> | |||
* <tr class="TableRowColor"><td>Right[$]</td><td>Y</td></tr> | |||
* <tr class="TableRowColor"><td>Space[$]</td><td>Y</td></tr> | |||
* <tr class="TableRowColor"><td>StrComp</td><td>Y</td></tr> |
@@ -464,18 +464,6 @@ public class DefaultDateFunctions | |||
return getOptionalIntParam(ctx, params, idx, 1, 0); | |||
} | |||
private static int getOptionalIntParam( | |||
LocaleContext ctx, Value[] params, int idx, int defValue, int useDefValue) { | |||
int val = defValue; | |||
if(params.length > idx) { | |||
val = params[idx].getAsLongInt(ctx); | |||
if(val == useDefValue) { | |||
val = defValue; | |||
} | |||
} | |||
return val; | |||
} | |||
private static int weekOfYear(EvalContext ctx, Value param, int firstDay, | |||
int firstWeekType) { | |||
Calendar cal = nonNullToCalendar(ctx, param); |
@@ -184,14 +184,4 @@ public class DefaultNumberFunctions | |||
return ValueSupport.toValue(Math.tan(param1.getAsDouble(ctx))); | |||
} | |||
}); | |||
// public static final Function VAL = registerFunc(new Func1("Val") { | |||
// @Override | |||
// protected Value eval1(EvalContext ctx, Value param1) { | |||
// // FIXME, maybe leverage ExpressionTokenizer.maybeParseNumberLiteral (note, leading - or + is valid, exponent form is valid) | |||
// } | |||
// }); | |||
} |
@@ -136,10 +136,7 @@ public class DefaultTextFunctions | |||
// 1 based offsets | |||
return ValueSupport.toValue(start + 1); | |||
} | |||
boolean ignoreCase = true; | |||
if(params.length > 3) { | |||
ignoreCase = doIgnoreCase(ctx, params[3]); | |||
} | |||
boolean ignoreCase = getIgnoreCase(ctx, params, 3); | |||
int end = s1Len - s2Len; | |||
while(start < end) { | |||
if(s1.regionMatches(ignoreCase, start, s2, 0, s2Len)) { | |||
@@ -183,10 +180,7 @@ public class DefaultTextFunctions | |||
// 1 based offsets | |||
--start; | |||
} | |||
boolean ignoreCase = true; | |||
if(params.length > 3) { | |||
ignoreCase = doIgnoreCase(ctx, params[3]); | |||
} | |||
boolean ignoreCase = getIgnoreCase(ctx, params, 3); | |||
start = Math.min(s1Len - s2Len, start - s2Len + 1); | |||
while(start >= 0) { | |||
if(s1.regionMatches(ignoreCase, start, s2, 0, s2Len)) { | |||
@@ -290,6 +284,54 @@ public class DefaultTextFunctions | |||
} | |||
}); | |||
public static final Function REPLACE = registerStringFunc(new FuncVar("Replace", 3, 6) { | |||
@Override | |||
protected Value evalVar(EvalContext ctx, Value[] params) { | |||
String str = params[0].getAsString(ctx); | |||
String searchStr = params[1].getAsString(ctx); | |||
String replStr = params[2].getAsString(ctx); | |||
int strLen = str.length(); | |||
int start = getOptionalIntParam(ctx, params, 3, 1) - 1; | |||
int count = getOptionalIntParam(ctx, params, 4, -1); | |||
boolean ignoreCase = getIgnoreCase(ctx, params, 5); | |||
if(start >= strLen) { | |||
return ValueSupport.EMPTY_STR_VAL; | |||
} | |||
int searchLen = searchStr.length(); | |||
if((searchLen == 0) || (count == 0)) { | |||
String result = str; | |||
if(start > 0) { | |||
result = str.substring(start); | |||
} | |||
return ValueSupport.toValue(result); | |||
} | |||
if(count < 0) { | |||
count = strLen; | |||
} | |||
StringBuilder result = new StringBuilder(strLen); | |||
int matchCount = 0; | |||
for(int i = start; i < strLen; ++i) { | |||
if((matchCount < count) && | |||
str.regionMatches(ignoreCase, i, searchStr, 0, searchLen)) { | |||
result.append(replStr); | |||
++matchCount; | |||
i += searchLen - 1; | |||
} else { | |||
result.append(str.charAt(i)); | |||
} | |||
} | |||
return ValueSupport.toValue(result.toString()); | |||
} | |||
}); | |||
public static final Function SPACE = registerStringFunc(new Func1("Space") { | |||
@Override | |||
protected Value eval1(EvalContext ctx, Value param1) { | |||
@@ -308,10 +350,7 @@ public class DefaultTextFunctions | |||
} | |||
String s1 = param1.getAsString(ctx); | |||
String s2 = param2.getAsString(ctx); | |||
boolean ignoreCase = true; | |||
if(params.length > 2) { | |||
ignoreCase = doIgnoreCase(ctx, params[2]); | |||
} | |||
boolean ignoreCase = getIgnoreCase(ctx, params, 2); | |||
int cmp = (ignoreCase ? | |||
s1.compareToIgnoreCase(s2) : s1.compareTo(s2)); | |||
// stupid java doesn't return 1, -1, 0... | |||
@@ -412,6 +451,14 @@ public class DefaultTextFunctions | |||
return str.substring(start, end); | |||
} | |||
private static boolean getIgnoreCase(EvalContext ctx, Value[] params, int idx) { | |||
boolean ignoreCase = true; | |||
if(params.length > idx) { | |||
ignoreCase = doIgnoreCase(ctx, params[idx]); | |||
} | |||
return ignoreCase; | |||
} | |||
private static boolean doIgnoreCase(LocaleContext ctx, Value paramCmp) { | |||
int cmpType = paramCmp.getAsLongInt(ctx); | |||
switch(cmpType) { |
@@ -254,4 +254,22 @@ public class FunctionSupport | |||
} | |||
return defValue; | |||
} | |||
public static int getOptionalIntParam( | |||
LocaleContext ctx, Value[] params, int idx, int defValue) { | |||
return getOptionalIntParam(ctx, params, idx, defValue, defValue); | |||
} | |||
public static int getOptionalIntParam( | |||
LocaleContext ctx, Value[] params, int idx, int defValue, int useDefValue) { | |||
int val = defValue; | |||
if(params.length > idx) { | |||
val = params[idx].getAsLongInt(ctx); | |||
if(val == useDefValue) { | |||
val = defValue; | |||
} | |||
} | |||
return val; | |||
} | |||
} |
@@ -205,6 +205,22 @@ public class DefaultFunctionsTest extends TestCase | |||
assertEquals(1.23d, eval("=Val(' 1 2 3 e -2 whatever')")); | |||
assertEquals(0d, eval("=Val(' whatever123 ')")); | |||
assertEquals(0d, eval("=Val('')")); | |||
assertEquals("faa", eval("=Replace('foo','o','a')")); | |||
assertEquals("faa", eval("=Replace('fOo','o','a')")); | |||
assertEquals("aa", eval("=Replace('foo','o','a',2)")); | |||
assertEquals("oo", eval("=Replace('foo','o','a',2,0)")); | |||
assertEquals("", eval("=Replace('foo','o','a',4)")); | |||
assertEquals("foo", eval("=Replace('foo','','a')")); | |||
assertEquals("o", eval("=Replace('foo','','a',3)")); | |||
assertEquals("fahhabahhaahha", eval("=Replace('fooboooo','OO','ahha')")); | |||
assertEquals("fahhaboooo", eval("=Replace('fooboooo','OO','ahha',1,1)")); | |||
assertEquals("fooboooo", eval("=Replace('fooboooo','OO','ahha',1,1,0)")); | |||
assertEquals("ahhabahhaahha", eval("=Replace('fooboooo','OO','ahha',2)")); | |||
assertEquals("obahhaahha", eval("=Replace('fooboooo','OO','ahha',3)")); | |||
assertEquals("fb", eval("=Replace('fooboooo','OO','')")); | |||
assertEquals("", eval("=Replace('','o','a')")); | |||
assertEquals("foo", eval("=Replace('foo','foobar','a')")); | |||
} | |||
public void testNumberFuncs() throws Exception |