Skip to content

Commit

Permalink
Added an optimization mechanism for the members lookup and a new sign…
Browse files Browse the repository at this point in the history
…ature to the Handler interface which receives a reference to the parent connection object.

git-svn-id: https://olap4j.svn.sourceforge.net/svnroot/olap4j/trunk@104 c6a108a4-781c-0410-a6c6-c2d559e19af0
  • Loading branch information
lucboudreau committed Jul 29, 2008
1 parent e8d3567 commit 2a32251
Show file tree
Hide file tree
Showing 2 changed files with 118 additions and 17 deletions.
51 changes: 48 additions & 3 deletions src/org/olap4j/driver/xmla/XmlaOlap4jConnection.java
Original file line number Diff line number Diff line change
Expand Up @@ -9,6 +9,7 @@
package org.olap4j.driver.xmla;

import org.olap4j.*;

import static org.olap4j.driver.xmla.XmlaOlap4jUtil.*;

import org.olap4j.driver.xmla.proxy.*;
Expand Down Expand Up @@ -575,7 +576,7 @@ <T extends Named> void populateList(
Element root = xxx(request);
for (Element o : childElements(root)) {
if (o.getLocalName().equals("row")) {
handler.handle(o, context, list);
handler.handle(o, context, list, this);
}
}
handler.sortList(list);
Expand Down Expand Up @@ -809,7 +810,9 @@ public void handle(Element row, Context context, List<XmlaOlap4jCatalog> list) {
}

static class CubeHandler extends HandlerImpl<XmlaOlap4jCube> {
public void handle(Element row, Context context, List<XmlaOlap4jCube> list)

public void handle(Element row, Context context,
List<XmlaOlap4jCube> list, XmlaOlap4jConnection connection)
throws OlapException
{
/*
Expand All @@ -834,7 +837,13 @@ public void handle(Element row, Context context, List<XmlaOlap4jCube> list)
String description = stringElement(row, "DESCRIPTION");
list.add(
new XmlaOlap4jCube(
context.olap4jSchema, cubeName, description));
context.olap4jSchema, cubeName, description, connection));
}

public void handle(Element row, Context context,
List<XmlaOlap4jCube> list) throws OlapException {
throw new RuntimeException(
"A cube object needs a reference to the connection who created it.");
}
}

Expand Down Expand Up @@ -1274,6 +1283,28 @@ void handle(
Element row,
Context context,
List<T> list) throws OlapException;

/**
* Converts an XML element from an XMLA result set into a metadata
* element and appends it to a list of metadata elements.
*
* @param row XMLA element
*
* @param context Context (schema, cube, dimension, etc.) that the
* request was executed in and that the element will belong to
*
* @param list List of metadata elements to append new metadata element
*
* @param connection A reference to the connection object which populated
* the object.
*
* @throws OlapException on error
*/
void handle(
Element row,
Context context,
List<T> list,
XmlaOlap4jConnection connection) throws OlapException;

/**
* Sorts a list of metadata elements.
Expand All @@ -1290,6 +1321,20 @@ static abstract class HandlerImpl<T extends Named> implements Handler<T> {
public void sortList(List<T> list) {
// do nothing - assume XMLA returned list in correct order
}

/**
* <p>Default implementation of the handle method with a reference to the
* connection object.
*
* @see org.olap4j.driver.xmla.XmlaOlap4jConnection.Handler
* #handle(org.w3c.dom.Element,
* org.olap4j.driver.xmla.XmlaOlap4jConnection.Context,
* java.util.List, org.olap4j.driver.xmla.XmlaOlap4jConnection)
*/
public void handle(Element row, Context context, List<T> list,
XmlaOlap4jConnection connection) throws OlapException {
this.handle(row, context, list);
}
}

static class Context {
Expand Down
84 changes: 70 additions & 14 deletions src/org/olap4j/driver/xmla/XmlaOlap4jCube.java
Original file line number Diff line number Diff line change
Expand Up @@ -45,25 +45,29 @@ class XmlaOlap4jCube implements Cube, Named
private final NamedList<XmlaOlap4jNamedSet> namedSets =
new NamedListImpl<XmlaOlap4jNamedSet>();
private final MetadataReader metadataReader;
private XmlaOlap4jConnection connection;

/**
* Creates an XmlaOlap4jCube.
*
* @param olap4jSchema Schema
* @param name Name
* @param description Description
* @param connection
*/
XmlaOlap4jCube(
XmlaOlap4jSchema olap4jSchema,
String name,
String description) throws OlapException
String description,
XmlaOlap4jConnection connection) throws OlapException
{
assert olap4jSchema != null;
assert description != null;
assert name != null;
this.olap4jSchema = olap4jSchema;
this.name = name;
this.description = description;
this.connection = connection;
this.metadataReader =
new CachingMetadataReader(
new RawMetadataReader());
Expand Down Expand Up @@ -427,28 +431,80 @@ public XmlaOlap4jMember lookupMemberByUniqueName(
/* (non-Javadoc)
* @see org.olap4j.driver.xmla.MetadataReader
* #lookupMembersByUniqueName(java.util.List, java.util.Map)
* TODO Optimize this process so we don't always send N requests for N members.
*/
public void lookupMembersByUniqueName(
List<String> memberUniqueNames,
Map<String, XmlaOlap4jMember> memberMap) throws OlapException
{
List<XmlaOlap4jMember> memberList =
if (connection.getDataSourceInfo()
.indexOf("Provider=Mondrian") != -1)
{
memberMap.putAll(this.mondrianMembersLookup(memberUniqueNames));
} else {
memberMap.putAll(this.genericMembersLookup(memberUniqueNames));
}
}

/**
* This is an optimized method for Mondrian servers members lookup.
* @param memberUniqueNames A list of the members to lookup
* @return A map of members with their unique name as a key
* @throws OlapException Gets thrown for communication errors
*/
private Map<String,XmlaOlap4jMember> mondrianMembersLookup(
List<String> memberUniqueNames) throws OlapException
{
final XmlaOlap4jConnection.Context context =
new XmlaOlap4jConnection.Context(
XmlaOlap4jCube.this, null, null, null);
final List<XmlaOlap4jMember> memberList =
new ArrayList<XmlaOlap4jMember>();
for (String currentMemberName : memberUniqueNames) {
memberList.add(
this.lookupMemberByUniqueName(currentMemberName));
olap4jSchema.olap4jCatalog.olap4jDatabaseMetaData.olap4jConnection
.populateList(
memberList,
context,
XmlaOlap4jConnection.MetadataRequest.MDSCHEMA_MEMBERS,
new XmlaOlap4jConnection.MemberHandler(),
new Object[] {
"CATALOG_NAME", olap4jSchema.olap4jCatalog.getName(),
"SCHEMA_NAME", olap4jSchema.getName(),
"CUBE_NAME", getName(),
"MEMBER_UNIQUE_NAME", memberUniqueNames
});
final Map<String,XmlaOlap4jMember> memberMap =
new HashMap<String,XmlaOlap4jMember>(memberUniqueNames.size());
for (XmlaOlap4jMember member : memberList) {
if (member != null) {
memberMap.put(member.getUniqueName(), member);
}
}
// All members have been found without errors,
// we can populate the map.
for (XmlaOlap4jMember currentMember : memberList) {
if (currentMember != null &&
!memberMap.containsKey(currentMember.getUniqueName()))
{
memberMap.put(currentMember.getUniqueName(),
currentMember);
return memberMap;
}

/**
* This is an generic method for members lookup.
* @param memberUniqueNames A list of the members to lookup
* @return A map of members with their unique name as a key
* @throws OlapException Gets thrown for communication errors
*/
private Map<String,XmlaOlap4jMember> genericMembersLookup(
List<String> memberUniqueNames) throws OlapException
{
final Map<String,XmlaOlap4jMember> memberMap =
new HashMap<String,XmlaOlap4jMember>(memberUniqueNames.size());
// Iterates through member names
for (String currentMemberName : memberUniqueNames) {
// Only lookup if it is not in the map yet
if (!memberMap.containsKey(currentMemberName)) {
XmlaOlap4jMember member =
this.lookupMemberByUniqueName(currentMemberName);
// Null members might mean calculated members
if (member != null) {
memberMap.put(member.getUniqueName(), member);
}
}
}
return memberMap;
}

public void lookupMemberRelatives(
Expand Down

0 comments on commit 2a32251

Please sign in to comment.