]> source.dussan.org Git - jackcess.git/commitdiff
implement Val function
authorJames Ahlborn <jtahlborn@yahoo.com>
Fri, 2 Nov 2018 20:14:59 +0000 (20:14 +0000)
committerJames Ahlborn <jtahlborn@yahoo.com>
Fri, 2 Nov 2018 20:14:59 +0000 (20:14 +0000)
git-svn-id: https://svn.code.sf.net/p/jackcess/code/jackcess/trunk@1214 f203690c-595d-4dc9-a70b-905162fa7fd2

src/main/java/com/healthmarketscience/jackcess/expr/package-info.java
src/main/java/com/healthmarketscience/jackcess/impl/expr/DefaultFunctions.java
src/main/java/com/healthmarketscience/jackcess/impl/expr/ValueSupport.java
src/test/java/com/healthmarketscience/jackcess/impl/expr/DefaultFunctionsTest.java

index 4db1b0d4c562e103a2692284d8aea9424e588b4a..e9f84db7bf9e917e932ae21f3f4e87863a0de17a 100644 (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>
index ae4d268ad7969dbec18d9213d19ff374f7968f2a..24f6d99715313a27d99478f098d28032ea752604 100644 (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);
index e2a7173042d177a382c4dc0d0cc8af655e8362fe..d0f8bf86d94a4a9c216f276f55fb8ef205529ae6 100644 (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) {
index 5f0a04592a5295bcb666ef2e4b6fbad11b471571..98aea88f7d7c5f98ccdaa9004514a858da211a29 100644 (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