Use UserVmDao for listVirtualMachines API to increase performance (#8012)

Co-authored-by: Marcus Sorensen <mls@apple.com>
This commit is contained in:
Marcus Sorensen 2023-10-26 00:44:09 -06:00 committed by GitHub
parent ea90848429
commit 4ff592ac2c
No known key found for this signature in database
GPG Key ID: 4AEE18F83AFDEB23
3 changed files with 540 additions and 339 deletions

View File

@ -1264,6 +1264,11 @@ public abstract class GenericDaoBase<T, ID extends Serializable> extends Compone
@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) {
@ -1274,18 +1279,27 @@ public abstract class GenericDaoBase<T, ID extends Serializable> extends Compone
}
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);
@ -1306,11 +1320,22 @@ public abstract class GenericDaoBase<T, ID extends Serializable> extends Compone
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());
}

View File

@ -18,6 +18,10 @@ package com.cloud.utils.db;
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;
@ -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;
@ -214,4 +219,51 @@ public class GenericDaoBaseTest {
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));
}
}