use of com.servoy.base.query.BaseQueryTable in project servoy-client by Servoy.
the class FindState method createFindStateJoins.
/**
* Find all processable related find states and create joins. A find state is processable when it has changed or when a related find state has changed.
* @param sqlSelect
* @param relations path to this state
* @param selectTable
* @param provider
* @return
* @throws RepositoryException
*/
public List<RelatedFindState> createFindStateJoins(QuerySelect sqlSelect, List<IRelation> relations, BaseQueryTable selectTable, IGlobalValueEntry provider) throws RepositoryException {
List<RelatedFindState> relatedFindStates = null;
List<Relation> searchRelations = getValidSearchRelations();
// find processable find states of related find states
for (Relation relation : searchRelations) {
if (relation != null) {
IFoundSetInternal set = relatedStates.get(relation.getName());
if (set != null && set.getSize() > 0) {
ISQLTableJoin existingJoin = (ISQLTableJoin) sqlSelect.getJoin(selectTable, relation.getName());
BaseQueryTable foreignQTable;
if (existingJoin == null) {
ITable foreignTable = parent.getFoundSetManager().getApplication().getFlattenedSolution().getTable(relation.getForeignDataSource());
foreignQTable = new QueryTable(foreignTable.getSQLName(), foreignTable.getDataSource(), foreignTable.getCatalog(), foreignTable.getSchema());
} else {
foreignQTable = existingJoin.getForeignTable();
}
FindState fs = (FindState) set.getRecord(0);
List<IRelation> nextRelations = new ArrayList<IRelation>(relations);
nextRelations.add(relation);
List<RelatedFindState> rfs = fs.createFindStateJoins(sqlSelect, nextRelations, foreignQTable, provider);
if (rfs != null && rfs.size() > 0) {
// changed related findstate, add self with join
if (relatedFindStates == null) {
relatedFindStates = rfs;
} else {
relatedFindStates.addAll(rfs);
}
if (existingJoin == null) {
sqlSelect.addJoin(SQLGenerator.createJoin(parent.getFoundSetManager().getApplication().getFlattenedSolution(), relation, selectTable, foreignQTable, false, provider));
}
}
}
}
}
// add yourself if you have changed or one or more related states has changed
if (isChanged() || (relatedFindStates != null && relatedFindStates.size() > 0)) {
if (relatedFindStates == null) {
relatedFindStates = new ArrayList<RelatedFindState>();
}
relatedFindStates.add(new RelatedFindState(this, relations, selectTable));
}
return relatedFindStates;
}
use of com.servoy.base.query.BaseQueryTable in project servoy-client by Servoy.
the class ViewFoundSet method addRealColumnToTableMap.
private void addRealColumnToTableMap(Map<BaseQueryTable, List<QueryColumn>> columnsInJoinsPerTable, QueryColumn column) {
select.getRealColumn(column).ifPresent(realColumn -> {
BaseQueryTable realcolumnTable = realColumn.getTable();
List<QueryColumn> list = columnsInJoinsPerTable.get(realcolumnTable);
if (list == null) {
list = new ArrayList<>();
columnsInJoinsPerTable.put(realcolumnTable, list);
}
list.add(realColumn);
});
}
use of com.servoy.base.query.BaseQueryTable in project servoy-client by Servoy.
the class QueryJoin method invert.
/**
* Invert the direction of this join.
*/
public void invert(String newName) {
// switch the tables
BaseQueryTable tmp = primaryTable;
primaryTable = ((TableExpression) foreignTableReference).getTable();
foreignTableReference = new TableExpression(tmp);
// the primary keys must be swapped around
if (condition != null) {
List conditions = condition.getConditions();
for (int i = 0; i < conditions.size(); i++) {
CompareCondition cond = (CompareCondition) conditions.get(i);
if ((cond.getOperator() & IBaseSQLCondition.OPERATOR_MASK) == IBaseSQLCondition.EQUALS_OPERATOR && cond.getOperand1() instanceof QueryColumn && cond.getOperand2() instanceof QueryColumn) {
conditions.set(i, new CompareCondition(cond.getOperator(), (QueryColumn) cond.getOperand2(), cond.getOperand1()));
}
}
}
// join type: left outer join becomes right outer join and vv. other joins stay the same
if (joinType == LEFT_OUTER_JOIN)
joinType = RIGHT_OUTER_JOIN;
else if (joinType == RIGHT_OUTER_JOIN)
joinType = LEFT_OUTER_JOIN;
this.name = newName;
}
use of com.servoy.base.query.BaseQueryTable in project servoy-client by Servoy.
the class QuerySelect method getRealColumn.
/**
* Get the real QueryColumn for a column in the query.
* <p>
* For a column from a table it is the column itself
* <br>
* For a column that refers to a derived table this function returns the actual column from the derived table.
* For example, <code>table_1.fld</code> is returned as real column for <code>col</code> in
* <pre>
* SELECT col
* FROM
* (SELECT fld
* FROM table_1) derived_table_name;
* </pre>
*
* @param column
*/
public Optional<QueryColumn> getRealColumn(IQuerySelectValue column) {
if (column == null) {
return Optional.empty();
}
QueryColumn qColumn = column.getColumn();
if (qColumn == null) {
return Optional.empty();
}
BaseQueryTable qTable = qColumn.getTable();
if (qTable.getDataSource() != null) {
// column on regular table
return Optional.of(qColumn);
}
// find real column in derived table
return AbstractBaseQuery.<DerivedTable>searchOne(this, new TypePredicate<>(DerivedTable.class, derivedTable -> derivedTable.getTable() == qTable)).map(DerivedTable::getQuery).map(QuerySelect::getColumns).flatMap(derivedColumns -> derivedColumns.stream().filter(Objects::nonNull).filter(dtcol -> qColumn.getName().equals(dtcol.getAlias()) || (dtcol.getColumn() != null && qColumn.getName().equals(dtcol.getColumn().getName()))).map(IQuerySelectValue::getColumn).filter(Objects::nonNull).findAny()).flatMap(// recursive for nested derived tables
this::getRealColumn);
}
use of com.servoy.base.query.BaseQueryTable in project servoy-client by Servoy.
the class QuerySelect method removeUnusedJoins.
/**
* Remove joins that whose foreign table is not referred to in this query.
*/
public void removeUnusedJoins(boolean keepInnerjoins) {
boolean updated = true;
while (joins != null && updated) {
updated = false;
int njoins = joins.size();
for (int i = 0; i < njoins && !updated; i++) {
ISQLJoin join = joins.get(i);
if (!(join instanceof ISQLTableJoin) || (keepInnerjoins && ((ISQLTableJoin) join).hasInnerJoin()) || ((ISQLTableJoin) join).isPermanent()) {
// count may depend on related records or is marked as permanent
continue;
}
if (!(((ISQLTableJoin) join).getForeignTableReference() instanceof TableExpression)) {
// derived table
continue;
}
BaseQueryTable joinTable = ((ISQLTableJoin) join).getForeignTable();
ObjectCountVisitor selectCounter = new ObjectCountVisitor(joinTable, true);
ObjectCountVisitor joinCounter = new ObjectCountVisitor(joinTable, true);
acceptVisitor(selectCounter);
join.acceptVisitor(joinCounter);
if (selectCounter.getCount() == joinCounter.getCount()) {
// the table is not referenced outside the join; it may be removed
if (njoins == 1) {
joins = null;
} else {
joins.remove(i);
}
updated = true;
}
}
}
}
Aggregations