Skip to content

Commit

Permalink
Fixes the trivial call on connect by populating lazily the list of da…
Browse files Browse the repository at this point in the history
…tabase properties, only when it is needed.

Fixes a concurrency issue in the XmlaOlap4jStatement where canceling before the request started would skip the cancellation.

Fixes an issue with the XMLA connection test where background statements were not cleaned after a cleanup.

git-svn-id: https://olap4j.svn.sourceforge.net/svnroot/olap4j/trunk@519 c6a108a4-781c-0410-a6c6-c2d559e19af0
  • Loading branch information
lucboudreau committed Mar 5, 2012
1 parent 41885cc commit 5e6aa68
Show file tree
Hide file tree
Showing 3 changed files with 63 additions and 23 deletions.
55 changes: 36 additions & 19 deletions src/org/olap4j/driver/xmla/XmlaOlap4jConnection.java
Original file line number Diff line number Diff line change
Expand Up @@ -40,6 +40,7 @@
import java.sql.*;
import java.util.*;
import java.util.Map.Entry;
import java.util.concurrent.atomic.AtomicBoolean;
import java.util.regex.Pattern;

import static org.olap4j.driver.xmla.XmlaOlap4jUtil.*;
Expand Down Expand Up @@ -138,7 +139,7 @@ abstract class XmlaOlap4jConnection implements OlapConnection {

private final URL serverUrlObject;

private HashSet<String> olap4jDatabaseProperties;
private HashSet<String> olap4jDatabaseProperties = null;

/**
* This is a private property used for development only.
Expand Down Expand Up @@ -257,22 +258,6 @@ public void setSessionId(String sessionId) {
null, null, null, null, null, null),
new XmlaOlap4jConnection.DatabaseHandler(),
null);

this.olap4jDatabaseProperties = new HashSet<String>();
final ResultSet rs =
this.olap4jDatabaseMetaData.getDatabaseProperties(null, null);
try {
while (rs.next()) {
String property =
rs.getString(XmlaConstants.Literal.PROPERTY_NAME.name());
if (property != null) {
property = property.toUpperCase();
olap4jDatabaseProperties.add(property);
}
}
} finally {
rs.close();
}
}

/**
Expand Down Expand Up @@ -331,7 +316,37 @@ static boolean acceptsURL(String url) {
return url.startsWith(CONNECT_STRING_PREFIX);
}

String makeConnectionPropertyList() {
String makeConnectionPropertyList() throws OlapException {
synchronized (propPopulation) {
if (propPopulation.get()) {
return "";
}
if (this.olap4jDatabaseProperties == null) {
propPopulation.set(true);
this.olap4jDatabaseProperties = new HashSet<String>();
final ResultSet rs =
this.olap4jDatabaseMetaData.getDatabaseProperties(null, null);
try {
while (rs.next()) {
String property =
rs.getString(XmlaConstants.Literal.PROPERTY_NAME.name());
if (property != null) {
property = property.toUpperCase();
olap4jDatabaseProperties.add(property);
}
}
} catch (SQLException e) {
throw new OlapException(e);
} finally {
propPopulation.set(false);
try {
rs.close();
} catch (SQLException e) {
throw new OlapException();
}
}
}
}
StringBuilder buf = new StringBuilder();
for (String prop : databaseProperties.keySet()) {
if (prop.startsWith(
Expand Down Expand Up @@ -908,6 +923,8 @@ Element executeMetadataRequest(String request) throws OlapException {
return findChild(returnElement, ROWSET_NS, "root");
}

final AtomicBoolean propPopulation = new AtomicBoolean(false);

/**
* Generates a metadata request.
*
Expand Down Expand Up @@ -2358,7 +2375,7 @@ enum MetadataRequest {
* @return whether this request requires a DatasourceName element
*/
public boolean requiresDatasourceName() {
return this != DISCOVER_DATASOURCES;
return this != DISCOVER_DATASOURCES && this != DISCOVER_PROPERTIES;
}

/**
Expand Down
18 changes: 14 additions & 4 deletions src/org/olap4j/driver/xmla/XmlaOlap4jStatement.java
Original file line number Diff line number Diff line change
Expand Up @@ -48,6 +48,9 @@ abstract class XmlaOlap4jStatement implements OlapStatement {
int timeoutSeconds;
Future<byte []> future;

// Tells this statement to cancel as soon as it starts.
private boolean cancelEarly = false;

/**
* Creates an XmlaOlap4jStatement.
*
Expand Down Expand Up @@ -130,10 +133,14 @@ public void setQueryTimeout(int seconds) throws SQLException {
}

public synchronized void cancel() {
if (!canceled) {
canceled = true;
if (future != null) {
future.cancel(true);
synchronized (this) {
if (!canceled) {
if (future != null) {
canceled = true;
future.cancel(true);
} else {
this.cancelEarly = true;
}
}
}
}
Expand Down Expand Up @@ -348,6 +355,9 @@ public CellSet executeOlapQuery(String mdx) throws OlapException {
olap4jConnection.serverInfos, request);
openCellSet = olap4jConnection.factory.newCellSet(this);
}
if (cancelEarly) {
cancel();
}
// Release the monitor before calling populate, so that cancel can
// grab the monitor if it needs to.
openCellSet.populate();
Expand Down
13 changes: 13 additions & 0 deletions testsrc/org/olap4j/ConnectionTest.java
Original file line number Diff line number Diff line change
Expand Up @@ -2576,6 +2576,13 @@ public void run() {
}
).start();
try {
// Because XMLA doesn't pass cancel statements,
// we set a query timeout to cleanup in the background
if (tester.getFlavor().equals(Flavor.XMLA)
|| tester.getFlavor().equals(Flavor.REMOTE_XMLA))
{
MondrianProperties.instance().QueryTimeout.set(5);
}
final CellSet cellSet = olapStatement.executeOlapQuery(
"SELECT Filter(\n"
+ " [Product].Members *\n"
Expand All @@ -2590,6 +2597,12 @@ public void run() {
assertTrue(
e.getMessage(),
e.getMessage().indexOf("Query canceled") >= 0);
} finally {
if (tester.getFlavor().equals(Flavor.XMLA)
|| tester.getFlavor().equals(Flavor.REMOTE_XMLA))
{
MondrianProperties.instance().QueryTimeout.set(0);
}
}
if (exceptions[0] != null) {
throw exceptions[0];
Expand Down

0 comments on commit 5e6aa68

Please sign in to comment.