diff --git a/src/org/olap4j/driver/xmla/XmlaOlap4jCube.java b/src/org/olap4j/driver/xmla/XmlaOlap4jCube.java index eb43ec9..18c4859 100644 --- a/src/org/olap4j/driver/xmla/XmlaOlap4jCube.java +++ b/src/org/olap4j/driver/xmla/XmlaOlap4jCube.java @@ -373,8 +373,17 @@ public void lookupMembersByUniqueName( // by delegating. if (!remainingMemberUniqueNames.isEmpty()) { super.lookupMembersByUniqueName( - memberUniqueNames, + remainingMemberUniqueNames, memberMap); + // Add the previously missing members into the cache. + for (String memberName : remainingMemberUniqueNames) { + XmlaOlap4jMember member = memberMap.get(memberName); + if (member != null) { + this.memberMap.put( + memberName, + new SoftReference(member)); + } + } } } diff --git a/testsrc/org/olap4j/XmlaConnectionTest.java b/testsrc/org/olap4j/XmlaConnectionTest.java index adb2226..4922586 100644 --- a/testsrc/org/olap4j/XmlaConnectionTest.java +++ b/testsrc/org/olap4j/XmlaConnectionTest.java @@ -2,12 +2,16 @@ import java.io.IOException; import java.net.URL; -import java.sql.DriverManager; -import java.util.Properties; +import java.security.*; +import java.sql.*; +import java.util.*; import java.util.concurrent.Future; +import mondrian.olap4j.MondrianInprocProxy; + import org.olap4j.driver.xmla.XmlaOlap4jDriver; import org.olap4j.driver.xmla.proxy.XmlaOlap4jProxy; +import org.olap4j.test.TestContext; import junit.framework.TestCase; @@ -15,6 +19,7 @@ public class XmlaConnectionTest extends TestCase { public static final String DRIVER_CLASS_NAME = "org.olap4j.driver.xmla.XmlaOlap4jDriver"; + private TestContext.Tester tester = null; static class XmlaOlap4jProxyMock implements XmlaOlap4jProxy { public byte[] get(URL url, String request) throws IOException { @@ -29,6 +34,34 @@ public Future submit(URL url, String request) { throw new RuntimeException("Non-Trivial Call!"); } } + public static class DoubleSubmissionTestProxy extends MondrianInprocProxy { + Map requests = new HashMap(); + public DoubleSubmissionTestProxy( + Map catalogNameUrls, + String urlString) + { + super(catalogNameUrls,urlString); + } + @Override + public byte[] get(URL url, String request) throws IOException { + this.checkup(request); + return super.get(url, request); + } +// @Override +// public Future submit(URL url, String request) { +// this.checkup(request); +// return super.submit(url, request); +// } + private void checkup(String request) { + String hash = Encoder.convertToHex(request.getBytes()); + if ( request.indexOf("MDSCHEMA_CUBES") == -1 && + this.requests.containsKey(hash)) { + throw new RuntimeException("DOUBLE-REQUEST"); + } else { + this.requests.put(hash,request); + } + } + } /** * this test verifies that the construction of the necessary @@ -57,6 +90,79 @@ public void testNoNonTrivalCallsOnConnect() throws Exception { fail("Non-Trival Call executed during construction of XmlaOlap4j Connection"); } } + + public void testNoDoubleQuerySubmission() throws Exception { + String oldValue = XmlaTester.getProxyClassName(); + XmlaTester.setProxyClassName( + DoubleSubmissionTestProxy.class.getName()); + if ( TestContext.getTestProperties() + .get(TestContext.Property.HELPER_CLASS_NAME.path) + .equals("org.olap4j.XmlaTester")) + { + try { + tester = TestContext.instance().getTester(); + Connection connection = tester.createConnection(); + Statement statement = connection.createStatement(); + final OlapStatement olapStatement = + tester.getWrapper().unwrap(statement, OlapStatement.class); + @SuppressWarnings("unused") + CellSet cellSet = + olapStatement.executeOlapQuery( + "SELECT\n" + + " {[Measures].[Unit Sales],\n" + + " [Measures].[Store Sales]} ON COLUMNS\n," + + " Crossjoin({[Gender].[M]}, [Product].Children) ON ROWS\n" + + "FROM [Sales]\n" + + "WHERE [Time].[1997].[Q2]"); + cellSet = + olapStatement.executeOlapQuery( + "SELECT\n" + + " {[Measures].[Unit Sales],\n" + + " [Measures].[Store Sales]} ON COLUMNS\n," + + " Crossjoin({[Gender].[M]}, [Product].Children) ON ROWS\n" + + "FROM [Sales]\n" + + "WHERE [Time].[1997].[Q3]"); + } catch(RuntimeException e) { + fail(e.getMessage()); + } + } + XmlaTester.setProxyClassName(oldValue); + } + + private static class Encoder { + private static String convertToHex(byte[] data) { + StringBuilder buf = new StringBuilder(); + for (int i = 0; i < data.length; i++) { + int halfbyte = (data[i] >>> 4) & 0x0F; + int two_halfs = 0; + do { + if ((0 <= halfbyte) && (halfbyte <= 9)) { + buf.append((char) ('0' + halfbyte)); + } else { + buf.append((char) ('a' + (halfbyte - 10))); + } + halfbyte = data[i] & 0x0F; + } while (two_halfs++ < 1); + } + return buf.toString(); + } + public static String SHA1(String text) { + MessageDigest md; + try { + md = MessageDigest.getInstance("SHA-1"); + } catch (NoSuchAlgorithmException e) { + try { + md = MessageDigest.getInstance("MD5"); + } catch (NoSuchAlgorithmException e1) { + throw new RuntimeException(e1); + } + } + byte[] sha1hash = new byte[40]; + md.update(text.getBytes(), 0, text.length()); + sha1hash = md.digest(); + return convertToHex(sha1hash); + } + } } // End XmlaConnectionTest.java diff --git a/testsrc/org/olap4j/XmlaTester.java b/testsrc/org/olap4j/XmlaTester.java index d333035..0d488d5 100644 --- a/testsrc/org/olap4j/XmlaTester.java +++ b/testsrc/org/olap4j/XmlaTester.java @@ -53,7 +53,7 @@ public XmlaTester() String urlString = properties.getProperty(TestContext.Property.CONNECT_URL.path); - final Class clazz = Class.forName("mondrian.olap4j.MondrianInprocProxy"); + final Class clazz = Class.forName(getProxyClassName()); final Constructor constructor = clazz.getConstructor(Map.class, String.class); this.proxy = @@ -115,12 +115,21 @@ public TestContext.Wrapper getWrapper() { return TestContext.Wrapper.NONE; } + public static void setProxyClassName(String clazz) { + PROXY_CLASS_NAME = clazz; + } + + public static String getProxyClassName() { + return PROXY_CLASS_NAME; + } + public static final String DRIVER_CLASS_NAME = "org.olap4j.driver.xmla.XmlaOlap4jDriver"; public static final String DRIVER_URL_PREFIX = "jdbc:xmla:"; private static final String USER = "user"; private static final String PASSWORD = "password"; + private static String PROXY_CLASS_NAME = "mondrian.olap4j.MondrianInprocProxy"; } // End XmlaTester.java