]> source.dussan.org Git - jackcess.git/commitdiff
implement replace function
authorJames Ahlborn <jtahlborn@yahoo.com>
Sat, 3 Nov 2018 06:06:36 +0000 (06:06 +0000)
committerJames Ahlborn <jtahlborn@yahoo.com>
Sat, 3 Nov 2018 06:06:36 +0000 (06:06 +0000)
git-svn-id: https://svn.code.sf.net/p/jackcess/code/jackcess/trunk@1215 f203690c-595d-4dc9-a70b-905162fa7fd2

src/main/java/com/healthmarketscience/jackcess/expr/package-info.java
src/main/java/com/healthmarketscience/jackcess/impl/expr/DefaultDateFunctions.java
src/main/java/com/healthmarketscience/jackcess/impl/expr/DefaultNumberFunctions.java
src/main/java/com/healthmarketscience/jackcess/impl/expr/DefaultTextFunctions.java
src/main/java/com/healthmarketscience/jackcess/impl/expr/FunctionSupport.java
src/test/java/com/healthmarketscience/jackcess/impl/expr/DefaultFunctionsTest.java

index e9f84db7bf9e917e932ae21f3f4e87863a0de17a..a8a697c85b258ec4aed391d431fc30febf0f0a6e 100644 (file)
@@ -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>
index 5752d58f889e69f592f75e300c04959c24e9b4d5..42b037e6d51f3e386c5aef4063f77b75e75805d8 100644 (file)
@@ -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);
index 2e8a04e56d8e6c5050dc528cddd6201af9e21e03..43bf5f4b05755b3805830cad92fef02372e530c3 100644 (file)
@@ -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)
-  //   }
-  // });
-
-
 }
index 42212cf97208a68e6517268fdd5ded1f8b84deeb..5291c3cfd2f5fd1dc2085120c5eabd6853220a28 100644 (file)
@@ -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) {
index 79e4609e92e7ce6c376e904ee829734e460b53b9..aa978e26c284e1ff6583e58dda718bdb6c49a751 100644 (file)
@@ -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;
+  }
+
 }
index 98aea88f7d7c5f98ccdaa9004514a858da211a29..4b6e38846b5d81db901cc108a63e334ee78d9fb2 100644 (file)
@@ -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