Skip to content
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
37 changes: 31 additions & 6 deletions framework/db/src/main/java/com/cloud/utils/db/GenericDaoBase.java
Original file line number Diff line number Diff line change
Expand Up @@ -1264,6 +1264,11 @@ protected StringBuilder createPartialSelectSql(SearchCriteria<?> sc, final boole

@DB()
protected void addJoins(StringBuilder str, Collection<JoinBuilder<SearchCriteria<?>>> joins) {
addJoins(str, joins, new HashMap<>());
}

@DB()
protected void addJoins(StringBuilder str, Collection<JoinBuilder<SearchCriteria<?>>> joins, Map<String, Integer> joinedTableNames) {
boolean hasWhereClause = true;
int fromIndex = str.lastIndexOf("WHERE");
if (fromIndex == -1) {
Expand All @@ -1274,18 +1279,27 @@ protected void addJoins(StringBuilder str, Collection<JoinBuilder<SearchCriteria
}

for (JoinBuilder<SearchCriteria<?>> join : joins) {
String joinTableName = join.getSecondAttribute().table;
String joinTableAlias = findNextJoinTableName(joinTableName, joinedTableNames);
StringBuilder onClause = new StringBuilder();
onClause.append(" ")
.append(join.getType().getName())
.append(" ")
.append(join.getSecondAttribute().table)
.append(" ON ")
.append(joinTableName);
if (!joinTableAlias.equals(joinTableName)) {
onClause.append(" ").append(joinTableAlias);
}
onClause.append(" ON ")
.append(join.getFirstAttribute().table)
.append(".")
.append(join.getFirstAttribute().columnName)
.append("=")
.append(join.getSecondAttribute().table)
.append(".")
.append("=");
if(!joinTableAlias.equals(joinTableName)) {
onClause.append(joinTableAlias);
} else {
onClause.append(joinTableName);
}
onClause.append(".")
.append(join.getSecondAttribute().columnName)
.append(" ");
str.insert(fromIndex, onClause);
Expand All @@ -1306,11 +1320,22 @@ protected void addJoins(StringBuilder str, Collection<JoinBuilder<SearchCriteria

for (JoinBuilder<SearchCriteria<?>> join : joins) {
if (join.getT().getJoins() != null) {
addJoins(str, join.getT().getJoins());
addJoins(str, join.getT().getJoins(), joinedTableNames);
}
}
}

protected static String findNextJoinTableName(String tableName, Map<String, Integer> usedTableNames) {
if (usedTableNames.containsKey(tableName)) {
Integer tableCounter = usedTableNames.get(tableName);
usedTableNames.put(tableName, ++tableCounter);
tableName = tableName + tableCounter;
} else {
usedTableNames.put(tableName, 0);
}
return tableName;
}

private void removeAndClause(StringBuilder sql) {
sql.delete(sql.length() - 4, sql.length());
}
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -18,6 +18,10 @@

import java.sql.ResultSet;
import java.sql.SQLException;
import java.util.ArrayList;
import java.util.Collection;
import java.util.HashMap;
import java.util.Map;

import org.junit.Assert;
import org.junit.Before;
Expand All @@ -36,6 +40,7 @@ public class GenericDaoBaseTest {
@Mock
SQLException mockedSQLException;

private static final DbTestDao dbTestDao = new DbTestDao();
private static final String INTEGRITY_CONSTRAINT_VIOLATION = "23000";
private static final int DUPLICATE_ENTRY_ERRO_CODE = 1062;

Expand Down Expand Up @@ -214,4 +219,51 @@ public void checkCountOfRecordsAgainstTheResultSetSizeTestCountSmallerThanResult

Assert.assertEquals(resultSetSize, result);
}

@Test
public void addJoinsTest() {
StringBuilder joinString = new StringBuilder();
Collection<JoinBuilder<SearchCriteria<?>>> joins = new ArrayList<>();

Attribute attr1 = new Attribute("table1", "column1");
Attribute attr2 = new Attribute("table2", "column2");
Attribute attr3 = new Attribute("table3", "column1");
Attribute attr4 = new Attribute("table4", "column2");

joins.add(new JoinBuilder<>(dbTestDao.createSearchCriteria(), attr1, attr2, JoinBuilder.JoinType.INNER));
joins.add(new JoinBuilder<>(dbTestDao.createSearchCriteria(), attr3, attr4, JoinBuilder.JoinType.INNER));
dbTestDao.addJoins(joinString, joins);

Assert.assertEquals(" INNER JOIN table2 ON table1.column1=table2.column2 INNER JOIN table4 ON table3.column1=table4.column2 ", joinString.toString());
}

@Test
public void multiJoinSameTableTest() {
StringBuilder joinString = new StringBuilder();
Collection<JoinBuilder<SearchCriteria<?>>> joins = new ArrayList<>();

Attribute tAc1 = new Attribute("tableA", "column1");
Attribute tAc2 = new Attribute("tableA", "column2");
Attribute tAc3 = new Attribute("tableA", "column3");
Attribute tBc2 = new Attribute("tableB", "column2");
Attribute tCc3 = new Attribute("tableC", "column3");
Attribute tDc4 = new Attribute("tableD", "column4");

joins.add(new JoinBuilder<>(dbTestDao.createSearchCriteria(), tBc2, tAc1, JoinBuilder.JoinType.INNER));
joins.add(new JoinBuilder<>(dbTestDao.createSearchCriteria(), tCc3, tAc2, JoinBuilder.JoinType.INNER));
joins.add(new JoinBuilder<>(dbTestDao.createSearchCriteria(), tDc4, tAc3, JoinBuilder.JoinType.INNER));
dbTestDao.addJoins(joinString, joins);

Assert.assertEquals(" INNER JOIN tableA ON tableB.column2=tableA.column1 INNER JOIN tableA tableA1 ON tableC.column3=tableA1.column2 INNER JOIN tableA tableA2 ON tableD.column4=tableA2.column3 ", joinString.toString());
}

@Test
public void findNextTableNameTest() {
Map<String, Integer> usedTables = new HashMap<>();

Assert.assertEquals("tableA", GenericDaoBase.findNextJoinTableName("tableA", usedTables));
Assert.assertEquals("tableA1", GenericDaoBase.findNextJoinTableName("tableA", usedTables));
Assert.assertEquals("tableA2", GenericDaoBase.findNextJoinTableName("tableA", usedTables));
Assert.assertEquals("tableA3", GenericDaoBase.findNextJoinTableName("tableA", usedTables));
}
}
Loading