Skip to content

Commit

Permalink
TEIID-3112 TEIID-3113 fix for salesforce issues and converting to real
Browse files Browse the repository at this point in the history
metadata
Conflicts:
	connectors/translator-salesforce/src/main/java/org/teiid/translator/salesforce/execution/visitors/JoinQueryVisitor.java
	connectors/translator-salesforce/src/test/java/org/teiid/translator/salesforce/execution/visitors/TestVisitors.java
  • Loading branch information
shawkins committed Mar 25, 2015
1 parent 9cdbb51 commit 66ad2e2
Show file tree
Hide file tree
Showing 7 changed files with 3,334 additions and 219 deletions.

This file was deleted.

This file was deleted.

@@ -1,6 +1,11 @@
package org.teiid.translator.salesforce;

import java.util.*;
import java.util.ArrayList;
import java.util.HashMap;
import java.util.Iterator;
import java.util.LinkedHashMap;
import java.util.List;
import java.util.Map;

import javax.resource.ResourceException;

Expand All @@ -11,17 +16,26 @@
import org.teiid.metadata.*;
import org.teiid.metadata.Column.SearchType;
import org.teiid.metadata.ProcedureParameter.Type;
import org.teiid.translator.*;
import org.teiid.translator.MetadataProcessor;
import org.teiid.translator.TranslatorException;
import org.teiid.translator.TranslatorProperty;
import org.teiid.translator.TranslatorProperty.PropertyType;
import org.teiid.translator.TypeFacility;

import com.sforce.soap.partner.*;
import com.sforce.soap.partner.ChildRelationship;
import com.sforce.soap.partner.DescribeGlobalResult;
import com.sforce.soap.partner.DescribeGlobalSObjectResult;
import com.sforce.soap.partner.DescribeSObjectResult;
import com.sforce.soap.partner.Field;
import com.sforce.soap.partner.FieldType;
import com.sforce.soap.partner.PicklistEntry;

public class SalesForceMetadataProcessor implements MetadataProcessor<SalesforceConnection>{
private MetadataFactory metadataFactory;
private SalesforceConnection connection;

private Map<String, Table> tableMap = new HashMap<String, Table>();
private List<Relationship> relationships = new ArrayList<Relationship>();
private Map<String, List<ChildRelationship>> relationships = new LinkedHashMap<String, List<ChildRelationship>>();
private boolean hasUpdateableColumn = false;
private List<Column> columns;
private boolean auditModelFields = false;
Expand Down Expand Up @@ -52,6 +66,8 @@ public class SalesForceMetadataProcessor implements MetadataProcessor<Salesforce
static final String TABLE_SUPPORTS_RETRIEVE = MetadataFactory.SF_URI+"Supports Retrieve"; //$NON-NLS-1$
@ExtensionMetadataProperty(applicable={Table.class}, datatype=Boolean.class, display="Supports Search")
static final String TABLE_SUPPORTS_SEARCH = MetadataFactory.SF_URI+"Supports Search"; //$NON-NLS-1$
@ExtensionMetadataProperty(applicable={Table.class}, datatype=String.class, display="The plural name")
public static final String TABLE_LABEL_PLURAL = MetadataFactory.SF_URI+"label_plural"; //$NON-NLS-1$

@ExtensionMetadataProperty(applicable={Column.class}, datatype=Boolean.class, display="Defaulted on Create")
static final String COLUMN_DEFAULTED = MetadataFactory.SF_URI+"Defaulted on Create"; //$NON-NLS-1$
Expand All @@ -67,7 +83,11 @@ public void process(MetadataFactory mf, SalesforceConnection connection) throws

processMetadata();

Procedure p1 = metadataFactory.addProcedure("GetUpdated"); //$NON-NLS-1$
addProcedrues(metadataFactory);
}

public static void addProcedrues(MetadataFactory metadataFactory) {
Procedure p1 = metadataFactory.addProcedure("GetUpdated"); //$NON-NLS-1$
p1.setAnnotation("Gets the updated objects"); //$NON-NLS-1$
ProcedureParameter param = metadataFactory.addProcedureParameter("ObjectName", TypeFacility.RUNTIME_NAMES.STRING, Type.In, p1); //$NON-NLS-1$
param.setAnnotation("ObjectName"); //$NON-NLS-1$
Expand All @@ -93,7 +113,7 @@ public void process(MetadataFactory mf, SalesforceConnection connection) throws
param = metadataFactory.addProcedureParameter("LatestDateCovered", TypeFacility.RUNTIME_NAMES.TIMESTAMP, Type.In, p2); //$NON-NLS-1$
param.setAnnotation("Latest Date Covered"); //$NON-NLS-1$
metadataFactory.addProcedureResultSetColumn("ID", TypeFacility.RUNTIME_NAMES.STRING, p2); //$NON-NLS-1$
metadataFactory.addProcedureResultSetColumn("DeletedDate", TypeFacility.RUNTIME_NAMES.TIMESTAMP, p2); //$NON-NLS-1$
metadataFactory.addProcedureResultSetColumn("DeletedDate", TypeFacility.RUNTIME_NAMES.TIMESTAMP, p2); //$NON-NLS-1$
}

public void processMetadata() throws TranslatorException {
Expand All @@ -119,43 +139,40 @@ public void processMetadata() throws TranslatorException {
}

private void addRelationships() {
for (Iterator<Relationship> iterator = relationships.iterator(); iterator.hasNext();) {
Relationship relationship = iterator.next();
if (!isModelAuditFields() && isAuditField(relationship.getForeignKeyField())) {
continue;
}

Table parent = tableMap.get(NameUtil.normalizeName(relationship.getParentTable()));
KeyRecord pk = parent.getPrimaryKey();
if (null == pk) {
throw new RuntimeException("ERROR !!primary key column not found!!"); //$NON-NLS-1$
}
ArrayList<String> columnNames = new ArrayList<String>();
columnNames.add(pk.getName());


Table child = tableMap.get(NameUtil.normalizeName(relationship.getChildTable()));
for (Map.Entry<String, List<ChildRelationship>> entry : this.relationships.entrySet()) {
for (ChildRelationship relationship : entry.getValue()) {

Column col = null;
columns = child.getColumns();
for (Iterator<Column> colIter = columns.iterator(); colIter.hasNext();) {
Column column = colIter.next();
if(column.getName().equals(relationship.getForeignKeyField())) {
col = column;
if (!isModelAuditFields() && isAuditField(relationship.getField())) {
continue;
}

Table parent = tableMap.get(NameUtil.normalizeName(entry.getKey()));
KeyRecord pk = parent.getPrimaryKey();
if (null == pk) {
throw new RuntimeException("ERROR !!primary key column not found!!"); //$NON-NLS-1$
}

Table child = tableMap.get(NameUtil.normalizeName(relationship.getChildSObject()));

Column col = null;
columns = child.getColumns();
for (Iterator<Column> colIter = columns.iterator(); colIter.hasNext();) {
Column column = colIter.next();
if(column.getName().equals(relationship.getField())) {
col = column;
}
}
if (null == col) throw new RuntimeException(
"ERROR !!foreign key column not found!! " + child.getName() + relationship.getField()); //$NON-NLS-1$


String name = "FK_" + parent.getName() + "_" + col.getName();//$NON-NLS-1$ //$NON-NLS-2$
ArrayList<String> columnNames = new ArrayList<String>();
columnNames.add(col.getName());
ForeignKey fk = metadataFactory.addForiegnKey(name, columnNames, parent.getName(), child);
//fk.setNameInSource(relationship.getRelationshipName()); //TODO: only needed for custom relationships
}
if (null == col) throw new RuntimeException(
"ERROR !!foreign key column not found!! " + child.getName() + relationship.getForeignKeyField()); //$NON-NLS-1$


String columnName = "FK_" + parent.getName() + "_" + col.getName();//$NON-NLS-1$ //$NON-NLS-2$
ArrayList<String> columnNames2 = new ArrayList<String>();
columnNames2.add(col.getName());
metadataFactory.addForiegnKey(columnName, columnNames2, parent.getName(), child);

}


}
}

public static boolean isAuditField(String name) {
Expand Down Expand Up @@ -193,6 +210,8 @@ private void addTable(DescribeGlobalSObjectResult object) throws TranslatorExcep
table.setProperty(TABLE_SUPPORTS_REPLICATE, String.valueOf(objectMetadata.isReplicateable()));
table.setProperty(TABLE_SUPPORTS_RETRIEVE, String.valueOf(objectMetadata.isRetrieveable()));
table.setProperty(TABLE_SUPPORTS_SEARCH, String.valueOf(objectMetadata.isSearchable()));
table.setProperty(TABLE_LABEL_PLURAL, objectMetadata.getLabelPlural());


hasUpdateableColumn = false;
addColumns(objectMetadata, table);
Expand All @@ -206,14 +225,7 @@ private void addTable(DescribeGlobalSObjectResult object) throws TranslatorExcep
private void getRelationships(DescribeSObjectResult objectMetadata) {
List<ChildRelationship> children = objectMetadata.getChildRelationships();
if(children != null && children.size() != 0) {
for (ChildRelationship childRelation : children) {
Relationship newRelation = new RelationshipImpl();
newRelation.setParentTable(objectMetadata.getName());
newRelation.setChildTable(childRelation.getChildSObject());
newRelation.setForeignKeyField(childRelation.getField());
newRelation.setCascadeDelete(childRelation.isCascadeDelete());
relationships.add(newRelation);
}
this.relationships.put(objectMetadata.getName(), children);
}
}

Expand Down
@@ -1,5 +1,6 @@
package org.teiid.translator.salesforce.execution.visitors;

import org.teiid.core.util.StringUtil;
import org.teiid.language.AggregateFunction;
import org.teiid.language.ColumnReference;
import org.teiid.language.Comparison;
Expand All @@ -12,6 +13,7 @@
import org.teiid.metadata.RuntimeMetadata;
import org.teiid.metadata.Table;
import org.teiid.translator.TranslatorException;
import org.teiid.translator.salesforce.SalesForceMetadataProcessor;


/**
Expand All @@ -31,6 +33,7 @@ public class JoinQueryVisitor extends SelectVisitor {
private Table leftTableInJoin;
private Table rightTableInJoin;
private Table childTable;
private String parentName;

public JoinQueryVisitor(RuntimeMetadata metadata) {
super(metadata);
Expand Down Expand Up @@ -66,7 +69,12 @@ public void visit(Join join) {
&& !rTableName.equals(lTableName)) {
// This is the join criteria, the one that is the ID is the parent.
Expression fKey = !isIdColumn(lExp) ? lExp : rExp;
table = childTable = (Table)((ColumnReference) fKey).getMetadataObject().getParent();
ColumnReference columnReference = (ColumnReference) fKey;
table = childTable = (Table)columnReference.getMetadataObject().getParent();
String name = columnReference.getMetadataObject().getNameInSource();
if (StringUtil.endsWithIgnoreCase(name, "id")) {
this.parentName = name.substring(0, name.length() - 2);
}
} else {
// Only add the criteria to the query if it is not the join criteria.
// The join criteria is implicit in the salesforce syntax.
Expand All @@ -83,7 +91,7 @@ public void visit(Join join) {
@Override
public String getQuery() throws TranslatorException {

if (isParentToChildJoin()) {
if (isChildToParentJoin()) {
return super.getQuery();
}
if (!exceptions.isEmpty()) {
Expand All @@ -100,7 +108,11 @@ public String getQuery() throws TranslatorException {
subselect.append(SPACE);

subselect.append(FROM).append(SPACE);
subselect.append(rightTableInJoin.getNameInSource()).append('s');
String pluralName = rightTableInJoin.getProperty(SalesForceMetadataProcessor.TABLE_LABEL_PLURAL, false);
if (pluralName == null) {
pluralName = rightTableInJoin.getNameInSource() + "s"; //$NON-NLS-1$
}
subselect.append(pluralName);
subselect.append(CLOSE).append(SPACE);

select.append(subselect);
Expand All @@ -112,8 +124,21 @@ public String getQuery() throws TranslatorException {
select.append(limitClause);
return select.toString();
}

@Override
void appendColumnReference(StringBuilder queryString, ColumnReference ref) {
if (isChildToParentJoin() && this.rightTableInJoin.equals(ref.getMetadataObject().getParent())
&& this.parentName != null) {
//TODO: a self join won't work with this logic
queryString.append(parentName);
queryString.append('.');
queryString.append(ref.getMetadataObject().getNameInSource());
} else {
super.appendColumnReference(queryString, ref);
}
}

public boolean isParentToChildJoin() {
public boolean isChildToParentJoin() {
return childTable.equals(leftTableInJoin);
}

Expand All @@ -124,7 +149,7 @@ void addSelect(String tableNameInSource, StringBuilder result, boolean addComma)
if (expression instanceof ColumnReference) {
Column element = ((ColumnReference) expression).getMetadataObject();
String tableName = element.getParent().getNameInSource();
if(!isParentToChildJoin() && !tableNameInSource.equals(tableName)) {
if(!isChildToParentJoin() && !tableNameInSource.equals(tableName)) {
continue;
}
if (!firstTime) {
Expand All @@ -141,7 +166,7 @@ void addSelect(String tableNameInSource, StringBuilder result, boolean addComma)
}
appendAggregateFunction(result, (AggregateFunction)expression);
} else {
throw new AssertionError("Unknown select symbol type" + symbol); //$NON-NLS-1$
throw new AssertionError("Unknown select symbol type " + symbol); //$NON-NLS-1$
}
}
if (!firstTime && addComma) {
Expand Down
Expand Up @@ -57,15 +57,15 @@ public class TestQueryExecutionImpl {
SObject so = new SObject();
so.setType("Account");
Element elem = Mockito.mock(Element.class);
Mockito.stub(elem.getLocalName()).toReturn("AccountName");
Mockito.stub(elem.getLocalName()).toReturn("Name");
so.getAny().add(elem);
qr.getRecords().add(so);
qr.setDone(false);
QueryResult finalQr = new QueryResult();
so.getAny().add(elem);
finalQr.getRecords().add(so);
finalQr.setDone(true);
Mockito.stub(sfc.query("SELECT Account.AccountName FROM Account", 0, false)).toReturn(qr);
Mockito.stub(sfc.query("SELECT Account.Name FROM Account", 0, false)).toReturn(qr);
Mockito.stub(sfc.queryMore(null, 0)).toReturn(finalQr);
QueryExecutionImpl qei = new QueryExecutionImpl(command, sfc, Mockito.mock(RuntimeMetadata.class), Mockito.mock(ExecutionContext.class));
qei.execute();
Expand Down

0 comments on commit 66ad2e2

Please sign in to comment.