Browse Source

implement Val function

git-svn-id: https://svn.code.sf.net/p/jackcess/code/jackcess/trunk@1214 f203690c-595d-4dc9-a70b-905162fa7fd2
tags/jackcess-2.2.1
James Ahlborn 5 years ago
parent
commit
504a1d8c0b

+ 1
- 1
src/main/java/com/healthmarketscience/jackcess/expr/package-info.java View File

@@ -111,7 +111,7 @@ limitations under the License.
* <tr class="TableRowColor"><td>Oct[$]</td><td>Y</td></tr>
* <tr class="TableRowColor"><td>Str[$]</td><td>Y</td></tr>
* <tr class="TableRowColor"><td>StringFromGUID</td><td></td></tr>
* <tr class="TableRowColor"><td>Val</td><td></td></tr>
* <tr class="TableRowColor"><td>Val</td><td>Y</td></tr>
* <tr class="TableRowColor"><td>CBool</td><td>Y</td></tr>
* <tr class="TableRowColor"><td>CByte</td><td>Y</td></tr>
* <tr class="TableRowColor"><td>CCur</td><td>Y</td></tr>

+ 46
- 37
src/main/java/com/healthmarketscience/jackcess/impl/expr/DefaultFunctions.java View File

@@ -350,43 +350,52 @@ public class DefaultFunctions
}
});

// public static final Function VAL = registerStringFunc(new Func1NullIsNull("Val") {
// @Override
// protected Value eval1(EvalContext ctx, Value param1) {
// String str = param1.getAsString(ctx).trim();

// if(str.length() == 0) {
// return ValueSupport.ZERO_VAL;
// }

// Matcher m = null;
// if(str.charAt(0) == ValueSupport.NUMBER_BASE_PREFIX) {
// // see if we can parse as a radix format
// if((m = ValueSupport.HEX_PAT.matcher(str)).find()) {
// BigInteger bi = ValueSupport.parseIntegerString(m.group(), 16);
// // FIXME, what to do with large numbers? to double or decimal?
// return ValueSupport.toValue(bi.intValue());
// } else if((m = ValueSupport.OCTAL_PAT.matcher(str)).find()) {
// BigInteger bi = ValueSupport.parseIntegerString(m.group(), 8);
// // FIXME, what to do with large numbers? to double or decimal?
// return ValueSupport.toValue(bi.intValue());
// }
// return ValueSupport.ZERO_VAL;
// }

// // parse ase normal "decimal" number.
// // FIXME - leading '+'? exponent?
// if((m = ValueSupport.NUMBER_PAT.matcher(str)).find()) {
// }
// // return ValueSupport.toValue(Integer.toHexString(lv).toUpperCase());
// return null;
// }
// });
public static final Function VAL = registerStringFunc(new Func1NullIsNull("Val") {
@Override
protected Value eval1(EvalContext ctx, Value param1) {

// strip all whitespace from string
String str = ValueSupport.WHITESPACE_PAT.matcher(param1.getAsString(ctx))
.replaceAll("");

if(str.length() == 0) {
return ValueSupport.ZERO_D_VAL;
}

Matcher m = null;

if(str.charAt(0) == ValueSupport.NUMBER_BASE_PREFIX) {

// see if we can parse as a radix format
BigInteger bi = null;
if((m = ValueSupport.HEX_PAT.matcher(str)).find()) {
bi = ValueSupport.parseIntegerString(m.group(), 16);
} else if((m = ValueSupport.OCTAL_PAT.matcher(str)).find()) {
bi = ValueSupport.parseIntegerString(m.group(), 8);
}

if(bi != null) {
// this function works differently than normal string to number
// conversion. it seems to coerce these values to a short/long int
// depending on the size of the number (which creates
// positive/negative values dependent on the value length)
int iVal = ((bi.bitLength() <= 16) ? bi.shortValue() : bi.intValue());
return ValueSupport.toValue((double)iVal);
}

} else {

// parse as normal "decimal" number.
if((m = ValueSupport.NUMBER_PAT.matcher(str)).find()) {
BigDecimal bd = new BigDecimal(m.group());
return ValueSupport.toValue(bd.doubleValue());
}
}

return ValueSupport.ZERO_D_VAL;
}
});

private static boolean stringIsNumeric(EvalContext ctx, Value param) {
try {
param.getAsBigDecimal(ctx);

+ 5
- 2
src/main/java/com/healthmarketscience/jackcess/impl/expr/ValueSupport.java View File

@@ -53,6 +53,7 @@ public class ValueSupport
public static final Value ZERO_VAL = FALSE_VAL;
public static final Value NEG_ONE_VAL = TRUE_VAL;
public static final Value ONE_VAL = new LongValue(1);
public static final Value ZERO_D_VAL = new DoubleValue(0d);

static final char NUMBER_BASE_PREFIX = '&';
static final Pattern OCTAL_PAT =
@@ -60,8 +61,10 @@ public class ValueSupport
static final Pattern HEX_PAT =
Pattern.compile("^" + NUMBER_BASE_PREFIX + "[hH]\\p{XDigit}+");
static final char CANON_DEC_SEP = '.';
static final Pattern NUMBER_PAT = Pattern.compile("^[-+]?[0-9]*[.]?[0-9]*");
static final Pattern NUMBER_PAT =
Pattern.compile("^[+-]?(([0-9]+[.]?[0-9]*)|([.][0-9]+))([eE][+-]?[0-9]+)?");
static final Pattern WHITESPACE_PAT = Pattern.compile("[ \\t\\r\\n]+");

private ValueSupport() {}

public static Value toValue(boolean b) {

+ 10
- 0
src/test/java/com/healthmarketscience/jackcess/impl/expr/DefaultFunctionsTest.java View File

@@ -195,6 +195,16 @@ public class DefaultFunctionsTest extends TestCase
} catch(EvalException e) {
assertTrue(e.getMessage().contains("Invalid function call"));
}

assertEquals(1615198d, eval("=Val(' 1615 198th Street N.E.')"));
assertEquals(-1d, eval("=Val(' &HFFFFwhatever')"));
assertEquals(131071d, eval("=Val(' &H1FFFFwhatever')"));
assertEquals(-1d, eval("=Val(' &HFFFFFFFFwhatever')"));
assertEquals(291d, eval("=Val(' &H123whatever')"));
assertEquals(83d, eval("=Val(' &O123whatever')"));
assertEquals(1.23d, eval("=Val(' 1 2 3 e -2 whatever')"));
assertEquals(0d, eval("=Val(' whatever123 ')"));
assertEquals(0d, eval("=Val('')"));
}

public void testNumberFuncs() throws Exception

Loading…
Cancel
Save