You are viewing a plain text version of this content. The canonical link for it is here.
Posted to commits@metamodel.apache.org by ka...@apache.org on 2019/03/09 15:42:40 UTC

[metamodel] branch master updated: METAMODEL-1207: Fix JDBC Database version parser edge cases.

This is an automated email from the ASF dual-hosted git repository.

kaspersor pushed a commit to branch master
in repository https://gitbox.apache.org/repos/asf/metamodel.git


The following commit(s) were added to refs/heads/master by this push:
     new 16d0b5a  METAMODEL-1207: Fix JDBC Database version parser edge cases.
16d0b5a is described below

commit 16d0b5a7c115f76f2f9ad7e7802992feea0f4771
Author: Kasper Sørensen <i....@gmail.com>
AuthorDate: Sat Mar 9 07:41:39 2019 -0800

    METAMODEL-1207: Fix JDBC Database version parser edge cases.
---
 CHANGES.md                                         |  4 +
 .../jdbc/dialects/AbstractQueryRewriter.java       | 36 +++------
 .../metamodel/jdbc/dialects/VersionParser.java     | 62 ++++++++++++++
 .../metamodel/jdbc/dialects/VersionParserTest.java | 94 ++++++++++++++++++++++
 4 files changed, 170 insertions(+), 26 deletions(-)

diff --git a/CHANGES.md b/CHANGES.md
index 298df07..abf1ab4 100644
--- a/CHANGES.md
+++ b/CHANGES.md
@@ -1,3 +1,7 @@
+### Apache MetaModel [WIP]
+
+ * [METAMODEL-1207] - Fix JDBC Database version parser edge cases.
+
 ### Apache MetaModel 5.2.1
 
  * [METAMODEL-1208] - Fixed closing of JDBC ResultSets when getting certain metadata.
diff --git a/jdbc/src/main/java/org/apache/metamodel/jdbc/dialects/AbstractQueryRewriter.java b/jdbc/src/main/java/org/apache/metamodel/jdbc/dialects/AbstractQueryRewriter.java
index 7092052..ea51a59 100644
--- a/jdbc/src/main/java/org/apache/metamodel/jdbc/dialects/AbstractQueryRewriter.java
+++ b/jdbc/src/main/java/org/apache/metamodel/jdbc/dialects/AbstractQueryRewriter.java
@@ -56,9 +56,8 @@ import org.slf4j.Logger;
 import org.slf4j.LoggerFactory;
 
 /**
- * Abstract implementation of query rewriter. This implementation delegates the
- * rewriting of the Query into several subtasks according to the query items to
- * be rendered. This makes it easy to overload single methods in order to
+ * Abstract implementation of query rewriter. This implementation delegates the rewriting of the Query into several
+ * subtasks according to the query items to be rendered. This makes it easy to overload single methods in order to
  * correct syntax quirks.
  */
 public abstract class AbstractQueryRewriter implements IQueryRewriter {
@@ -103,10 +102,9 @@ public abstract class AbstractQueryRewriter implements IQueryRewriter {
     }
 
     /**
-     * Method to modify query before rewriting begins. Overwrite this method if
-     * you want to change parts of the query that are not just rendering
-     * related. Cloning the query before modifying is recommended in order to
-     * not violate referential integrity of clients (the query is mutable).
+     * Method to modify query before rewriting begins. Overwrite this method if you want to change parts of the query
+     * that are not just rendering related. Cloning the query before modifying is recommended in order to not violate
+     * referential integrity of clients (the query is mutable).
      * 
      * @param query
      * @return the modified query
@@ -302,7 +300,7 @@ public abstract class AbstractQueryRewriter implements IQueryRewriter {
         }
         return item.toSql(isSchemaIncludedInColumnPaths());
     }
-    
+
     @Override
     public void setStatementParameter(PreparedStatement st, int valueIndex, Column column, Object value)
             throws SQLException {
@@ -404,7 +402,7 @@ public abstract class AbstractQueryRewriter implements IQueryRewriter {
             throw e;
         }
     }
-    
+
     protected Time toTime(Date value) {
         if (value instanceof Time) {
             return (Time) value;
@@ -422,7 +420,7 @@ public abstract class AbstractQueryRewriter implements IQueryRewriter {
         cal.setTime((Date) value);
         return new Timestamp(cal.getTimeInMillis());
     }
-    
+
     @Override
     public Object getResultSetValue(ResultSet resultSet, int columnIndex, Column column) throws SQLException {
         final ColumnType type = column.getType();
@@ -462,24 +460,10 @@ public abstract class AbstractQueryRewriter implements IQueryRewriter {
     }
 
     protected boolean isSupportedVersion(String databaseProductName, int databaseVersion) {
-
-        if(databaseProductName.equals(_dataContext.getDatabaseProductName())
-                && databaseVersion <= getDatabaseMajorVersion(_dataContext.getDatabaseVersion())) {
+        if (databaseProductName.equals(_dataContext.getDatabaseProductName())
+                && databaseVersion <= VersionParser.getMajorVersion(_dataContext.getDatabaseVersion())) {
             return true;
         }
         return false;
     }
-
-    private int getDatabaseMajorVersion(String version) {
-        int firstDot = -1;
-        if(version != null) {
-            version = version.replaceAll("[^0-9.]+", "");
-            firstDot = version.indexOf('.');
-        }
-        if(firstDot >= 0) {
-            return Integer.valueOf(version.substring(0, firstDot));
-        } else {
-            return 0;
-        }
-    }
 }
\ No newline at end of file
diff --git a/jdbc/src/main/java/org/apache/metamodel/jdbc/dialects/VersionParser.java b/jdbc/src/main/java/org/apache/metamodel/jdbc/dialects/VersionParser.java
new file mode 100644
index 0000000..83497d5
--- /dev/null
+++ b/jdbc/src/main/java/org/apache/metamodel/jdbc/dialects/VersionParser.java
@@ -0,0 +1,62 @@
+/**
+ * Licensed to the Apache Software Foundation (ASF) under one
+ * or more contributor license agreements.  See the NOTICE file
+ * distributed with this work for additional information
+ * regarding copyright ownership.  The ASF licenses this file
+ * to you under the Apache License, Version 2.0 (the
+ * "License"); you may not use this file except in compliance
+ * with the License.  You may obtain a copy of the License at
+ *
+ *   http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing,
+ * software distributed under the License is distributed on an
+ * "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY
+ * KIND, either express or implied.  See the License for the
+ * specific language governing permissions and limitations
+ * under the License.
+ */
+package org.apache.metamodel.jdbc.dialects;
+
+import java.util.regex.Matcher;
+import java.util.regex.Pattern;
+
+/**
+ * This class is responsible for parsing version numbers in software products. Version strings are expected to be
+ * numeric and dot-separated.
+ */
+class VersionParser {
+    private static final Pattern versionPattern = Pattern.compile("[0-9]+(\\.[0-9]+)+");
+
+    private VersionParser() {
+    }
+
+    /**
+     * @param stringToParse the string that contains the version.
+     * @return If the version exists returns the full version else empty string.
+     */
+    public static String getVersion(String stringToParse) {
+        if (stringToParse != null) {
+            Matcher matcher = versionPattern.matcher(stringToParse);
+            if (matcher.find()) {
+                return matcher.group();
+            }
+        }
+        return "";
+    }
+
+    /**
+     * @param stringToParse the string that contains the version.
+     * @return If the version exists returns only the number(s) before the first dot else 0.
+     */
+    public static int getMajorVersion(String stringToParse) {
+        String fullVersion = getVersion(stringToParse);
+        if (fullVersion != null) {
+            int firstDot = fullVersion.indexOf('.');
+            if (firstDot >= 0) {
+                return Integer.valueOf(fullVersion.substring(0, firstDot));
+            }
+        }
+        return -1;
+    }
+}
diff --git a/jdbc/src/test/java/org/apache/metamodel/jdbc/dialects/VersionParserTest.java b/jdbc/src/test/java/org/apache/metamodel/jdbc/dialects/VersionParserTest.java
new file mode 100644
index 0000000..7fa6e8a
--- /dev/null
+++ b/jdbc/src/test/java/org/apache/metamodel/jdbc/dialects/VersionParserTest.java
@@ -0,0 +1,94 @@
+/**
+ * Licensed to the Apache Software Foundation (ASF) under one
+ * or more contributor license agreements.  See the NOTICE file
+ * distributed with this work for additional information
+ * regarding copyright ownership.  The ASF licenses this file
+ * to you under the Apache License, Version 2.0 (the
+ * "License"); you may not use this file except in compliance
+ * with the License.  You may obtain a copy of the License at
+ *
+ *   http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing,
+ * software distributed under the License is distributed on an
+ * "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY
+ * KIND, either express or implied.  See the License for the
+ * specific language governing permissions and limitations
+ * under the License.
+ */
+package org.apache.metamodel.jdbc.dialects;
+
+import junit.framework.TestCase;
+
+public class VersionParserTest extends TestCase {
+
+    public void testGetVersion() throws Exception {
+        String version = VersionParser.getVersion("10.11.0");
+        assertEquals("10.11.0", version);
+    }
+
+    public void testGetVersionEmpty() throws Exception {
+        String version = VersionParser.getVersion("string with out version");
+        assertEquals("", version);
+    }
+
+    public void testGetVersionNull() throws Exception {
+        String version = VersionParser.getVersion(null);
+        assertEquals("", version);
+    }
+
+    public void testGetVersionWithLetters() throws Exception {
+        String version = VersionParser.getVersion("test 10.11.0V test");
+        assertEquals("10.11.0", version);
+    }
+
+    public void testGetVersionWithSpecialChars() throws Exception {
+        String version = VersionParser.getVersion("!@#test. 10.11.0V .test");
+        assertEquals("10.11.0", version);
+    }
+
+    public void testGetVersionWithLettersAndNumbers() throws Exception {
+        String version = VersionParser.getVersion("10 55g test 10.11.0 test 100");
+        assertEquals("10.11.0", version);
+    }
+
+    public void testGetVersionMultipleVersions() throws Exception {
+        String version = VersionParser.getVersion("test 10.11.0 11.11 test");
+        assertEquals("10.11.0", version);
+    }
+
+    public void testGetMajorVersion() throws Exception {
+        int version = VersionParser.getMajorVersion("10.11.0");
+        assertEquals(10, version);
+    }
+
+    public void testGetMajorVersionEmpty() throws Exception {
+        int version = VersionParser.getMajorVersion("string with out version");
+        assertEquals(-1, version);
+    }
+
+    public void testGetMajorVersionNull() throws Exception {
+        int version = VersionParser.getMajorVersion(null);
+        assertEquals(-1, version);
+    }
+
+    public void testGetMajorVersionWithLetters() throws Exception {
+        int version = VersionParser.getMajorVersion("test 10.11.0V test");
+        assertEquals(10, version);
+    }
+
+    public void testGetMajorVersionWithSpecialChars() throws Exception {
+        int version = VersionParser.getMajorVersion("!@#test. .10.11.0V .test");
+        assertEquals(10, version);
+    }
+
+    public void testGetMajorVersionWithLettersAndNumbers() throws Exception {
+        int version = VersionParser.getMajorVersion("10 55g test 10.11.0 test 100");
+        assertEquals(10, version);
+    }
+
+    public void testGetMajorVersionMultipleVersions() throws Exception {
+        int version = VersionParser.getMajorVersion("test 10.11.0V 11.11 test");
+        assertEquals(10, version);
+    }
+}