Skip to content

Commit

Permalink
XMLA driver: add member cache; call MDSCHEMA_MEMBERS with multiple un…
Browse files Browse the repository at this point in the history
…ique-names. Hierarchy.getDefaultMember() now throws OlapException. XmlaTester caches connections.

git-svn-id: https://olap4j.svn.sourceforge.net/svnroot/olap4j/trunk@68 c6a108a4-781c-0410-a6c6-c2d559e19af0
  • Loading branch information
julianhyde committed Feb 1, 2008
1 parent 14ca2de commit 3e562cf
Show file tree
Hide file tree
Showing 12 changed files with 489 additions and 227 deletions.
88 changes: 88 additions & 0 deletions src/org/olap4j/driver/xmla/MetadataReader.java
Original file line number Diff line number Diff line change
@@ -0,0 +1,88 @@
/*
// This software is subject to the terms of the Common Public License
// Agreement, available at the following URL:
// http://www.opensource.org/licenses/cpl.html.
// Copyright (C) 2008-2008 Julian Hyde
// All Rights Reserved.
// You must accept the terms of that agreement to use this software.
*/
package org.olap4j.driver.xmla;

import org.olap4j.OlapException;
import org.olap4j.metadata.Member;

import java.util.*;

/**
* Can read metadata, in particular members.
*
* @author jhyde
* @version $Id: $
* @since Jan 14, 2008
*/
interface MetadataReader {
/**
* Looks up a member by its unique name.
*
* <p>Not part of public olap4j API.
*
* @param memberUniqueName Unique name of member
* @return Member, or null if not found
* @throws org.olap4j.OlapException if error occurs
*/
XmlaOlap4jMember lookupMemberByUniqueName(
String memberUniqueName)
throws OlapException;

/**
* Looks up a list of members by their unique name and writes the results
* into a map.
*
* <p>Not part of public olap4j API.
*
* @param memberUniqueNames List of unique names of member
*
* @param memberMap Map to populate with members
*
* @throws org.olap4j.OlapException if error occurs
*/
void lookupMembersByUniqueName(
List<String> memberUniqueNames,
Map<String, XmlaOlap4jMember> memberMap)
throws OlapException;

/**
* Looks a member by its unique name and returns members related by
* the specified tree-operations.
*
* <p>Not part of public olap4j API.
*
* @param memberUniqueName Unique name of member
*
* @param treeOps Collection of tree operations to travel relative to
* given member in order to create list of members
*
* @param list list to be populated with members related to the given
* member, or empty set if the member is not found
*
* @throws org.olap4j.OlapException if error occurs
*/
void lookupMemberRelatives(
Set<Member.TreeOp> treeOps,
String memberUniqueName,
List<XmlaOlap4jMember> list) throws OlapException;

/**
* Looks up members of a given level.
*
* @param level Level
*
* @throws org.olap4j.OlapException if error occurs
*
* @return list of members at in the level
*/
List<XmlaOlap4jMember> getLevelMembers(XmlaOlap4jLevel level)
throws OlapException;
}

// End MetadataReader.java
29 changes: 27 additions & 2 deletions src/org/olap4j/driver/xmla/XmlaOlap4jCellSet.java
Original file line number Diff line number Diff line change
Expand Up @@ -182,6 +182,32 @@ void populate() throws OlapException {
int ordinal = 0;
final Map<Property, String> propertyValues =
new HashMap<Property, String>();

// First pass, gather up a list of member unique names to fetch
// all at once.
//
// NOTE: This approach allows the driver to fetch a large number
// of members in one round trip, which is much more efficient.
// However, if the axis has a very large number of members, the map
// may use too much memory. This is an unresolved issue.
final MetadataReader metadataReader =
metaData.cube.getMetadataReader();
final Map<String, XmlaOlap4jMember> memberMap =
new HashMap<String, XmlaOlap4jMember>();
List<String> uniqueNames = new ArrayList<String>();
for (Element tupleNode
: findChildren(tuplesNode, MDDATASET_NS, "Tuple"))
{
for (Element memberNode
: findChildren(tupleNode, MDDATASET_NS, "Member"))
{
final String uname = stringElement(memberNode, "UName");
uniqueNames.add(uname);
}
}
metadataReader.lookupMembersByUniqueName(uniqueNames, memberMap);

// Second pass, populate the axis.
for (Element tupleNode
: findChildren(tuplesNode, MDDATASET_NS, "Tuple"))
{
Expand All @@ -192,8 +218,7 @@ void populate() throws OlapException {
String hierarchyName =
memberNode.getAttribute("Hierarchy");
final String uname = stringElement(memberNode, "UName");
Member member =
metaData.cube.lookupMemberByUniqueName(uname);
Member member = memberMap.get(uname);
if (member == null) {
final String caption =
stringElement(memberNode, "Caption");
Expand Down
40 changes: 33 additions & 7 deletions src/org/olap4j/driver/xmla/XmlaOlap4jConnection.java
Original file line number Diff line number Diff line change
Expand Up @@ -396,7 +396,7 @@ <T extends Named> void populateList(
Context context,
MetadataRequest metadataRequest,
Handler<T> handler,
String... restrictions) throws OlapException
Object[] restrictions) throws OlapException
{
String request =
generateRequest(context, metadataRequest, restrictions);
Expand Down Expand Up @@ -474,10 +474,24 @@ Element xxx(String request) throws OlapException {
return findChild(returnElement, ROWSET_NS, "root");
}

/**
* Generates a metadata request.
*
* <p>The list of restrictions must have even length. Even elements must
* be a string (the name of the restriction); odd elements must be either
* a string (the value of the restriction) or a list of strings (multiple
* values of the restriction)
*
*
* @param context Context
* @param metadataRequest Metadata request
* @param restrictions List of restrictions
* @return XMLA request
*/
public String generateRequest(
Context context,
MetadataRequest metadataRequest,
String... restrictions)
Object[] restrictions)
{
final String dataSourceInfo =
context.olap4jConnection.getDataSourceInfo();
Expand All @@ -499,11 +513,23 @@ public String generateRequest(
throw new IllegalArgumentException();
}
for (int i = 0; i < restrictions.length; i += 2) {
final String restriction = restrictions[i];
final String value = restrictions[i + 1];
buf.append("<").append(restriction).append(">");
buf.append(xmlEncode(value));
buf.append("</").append(restriction).append(">");
final String restriction = (String) restrictions[i];
final Object o = restrictions[i + 1];
if (o instanceof String) {
buf.append("<").append(restriction).append(">");
final String value = (String) o;
buf.append(xmlEncode(value));
buf.append("</").append(restriction).append(">");

} else {
//noinspection unchecked
List<String> valueList = (List<String>) o;
for (String value : valueList) {
buf.append("<").append(restriction).append(">");
buf.append(xmlEncode(value));
buf.append("</").append(restriction).append(">");
}
}
}
}
buf.append(" </RestrictionList>\n"
Expand Down
Loading

0 comments on commit 3e562cf

Please sign in to comment.