use of org.sql.generation.api.grammar.builders.booleans.BooleanBuilder in project qi4j-sdk by Qi4j.
the class AbstractSQLQuerying method modifyFromClauseAndWhereClauseToGetValue.
// TODO refactor this monster of a method to something more understandable
protected Integer modifyFromClauseAndWhereClauseToGetValue(final QualifiedName qName, Object value, final Specification<Composite> predicate, final Boolean negationActive, final Integer currentTableIndex, final ModifiableInt maxTableIndex, final String columnName, final String collectionPath, final SQLVendor vendor, final BooleanBuilder whereClause, final BooleanBuilder afterWhere, final TableReferenceBuilder fromClause, final GroupByBuilder groupBy, final BooleanBuilder having, final List<QNameJoin> qNameJoins, Map<String, Object> variables, final List<Object> values, final List<Integer> valueSQLTypes) {
if (value instanceof Variable) {
value = variables.get(((Variable) value).variableName());
}
final String schemaName = this._state.schemaName().get();
Integer result = 1;
final BooleanFactory b = vendor.getBooleanFactory();
final LiteralFactory l = vendor.getLiteralFactory();
final ColumnsFactory c = vendor.getColumnsFactory();
final QueryFactory q = vendor.getQueryFactory();
final TableReferenceFactory t = vendor.getTableReferenceFactory();
if (value instanceof Collection<?>) {
// Collection
Integer collectionIndex = 0;
Boolean collectionIsSet = value instanceof Set<?>;
Boolean topLevel = collectionPath.equals(DBNames.QNAME_TABLE_COLLECTION_PATH_TOP_LEVEL_NAME);
String collTable = TABLE_NAME_PREFIX + currentTableIndex;
String collCol = DBNames.QNAME_TABLE_COLLECTION_PATH_COLUMN_NAME;
ColumnReferenceByName collColExp = c.colName(collTable, collCol);
BooleanBuilder collectionCondition = b.booleanBuilder();
if (topLevel && negationActive) {
afterWhere.and(b.booleanBuilder(b.neq(collColExp, l.s(DBNames.QNAME_TABLE_COLLECTION_PATH_TOP_LEVEL_NAME))).or(b.isNull(collColExp)).createExpression());
}
Integer totalItemsProcessed = 0;
for (Object item : (Collection<?>) value) {
String path = collectionPath + DBNames.QNAME_TABLE_COLLECTION_PATH_SEPARATOR + (collectionIsSet ? "*{1,}" : collectionIndex);
Boolean isCollection = (item instanceof Collection<?>);
BooleanBuilder newWhere = b.booleanBuilder();
if (!isCollection) {
newWhere.reset(b.regexp(collColExp, l.s(path)));
}
totalItemsProcessed = totalItemsProcessed + modifyFromClauseAndWhereClauseToGetValue(qName, item, predicate, negationActive, currentTableIndex, maxTableIndex, columnName, path, vendor, newWhere, afterWhere, fromClause, groupBy, having, qNameJoins, variables, values, valueSQLTypes);
++collectionIndex;
collectionCondition.or(newWhere.createExpression());
}
result = totalItemsProcessed;
if (topLevel) {
if (totalItemsProcessed == 0) {
collectionCondition.and(b.isNotNull(collColExp)).and(b.eq(collColExp, l.l(DBNames.QNAME_TABLE_COLLECTION_PATH_TOP_LEVEL_NAME)));
} else if (!negationActive) {
groupBy.addGroupingElements(q.groupingElement(c.colName(TABLE_NAME_PREFIX + currentTableIndex, DBNames.ENTITY_TABLE_PK_COLUMN_NAME)));
having.and(b.eq(l.func(SQLFunctions.COUNT, c.colName(TABLE_NAME_PREFIX + currentTableIndex, DBNames.QNAME_TABLE_VALUE_COLUMN_NAME)), l.n(totalItemsProcessed)));
}
}
whereClause.and(collectionCondition.createExpression());
} else if (value instanceof ValueComposite) {
// @formatter:off
for (Property<?> property : Qi4j.FUNCTION_COMPOSITE_INSTANCE_OF.map((ValueComposite) value).state().properties()) {
Boolean qNameJoinDone = false;
Integer sourceIndex = maxTableIndex.getInt();
Integer targetIndex = sourceIndex + 1;
for (QNameJoin join : qNameJoins) {
if (join.getSourceQName().equals(qName)) {
sourceIndex = join.getSourceTableIndex();
if (join.getTargetQName().equals(spi.propertyDescriptorFor(property).qualifiedName())) {
// This join has already been done once
qNameJoinDone = true;
targetIndex = join.getTargetTableIndex();
break;
}
}
}
if (!qNameJoinDone) {
// @formatter:off
QNameInfo info = _state.qNameInfos().get().get(spi.propertyDescriptorFor(property).qualifiedName());
String prevTableName = TABLE_NAME_PREFIX + sourceIndex;
String nextTableName = TABLE_NAME_PREFIX + targetIndex;
fromClause.addQualifiedJoin(JoinType.LEFT_OUTER, t.table(t.tableName(schemaName, info.getTableName()), t.tableAlias(TABLE_NAME_PREFIX + targetIndex)), t.jc(b.booleanBuilder(b.eq(c.colName(prevTableName, DBNames.ALL_QNAMES_TABLE_PK_COLUMN_NAME), c.colName(nextTableName, DBNames.QNAME_TABLE_PARENT_QNAME_COLUMN_NAME))).and(b.eq(c.colName(prevTableName, DBNames.ENTITY_TABLE_PK_COLUMN_NAME), c.colName(nextTableName, DBNames.ENTITY_TABLE_PK_COLUMN_NAME))).createExpression()));
// @formatter:on
qNameJoins.add(new QNameJoin(qName, spi.propertyDescriptorFor(property).qualifiedName(), sourceIndex, targetIndex));
maxTableIndex.setInt(maxTableIndex.getInt() + 1);
}
modifyFromClauseAndWhereClauseToGetValue(spi.propertyDescriptorFor(property).qualifiedName(), property.get(), predicate, negationActive, targetIndex, maxTableIndex, columnName, collectionPath, vendor, whereClause, afterWhere, fromClause, groupBy, having, qNameJoins, variables, values, valueSQLTypes);
}
// @formatter:on
} else {
// Primitive
ColumnReferenceByName valueCol = c.colName(TABLE_NAME_PREFIX + currentTableIndex, columnName);
if (value == null) {
whereClause.and(b.isNull(valueCol));
} else {
Object dbValue = value;
if (Enum.class.isAssignableFrom(value.getClass())) {
dbValue = this._state.enumPKs().get().get(value.getClass().getName());
}
whereClause.and(b.and(b.isNotNull(valueCol), this.getOperator(predicate).getExpression(b, valueCol, l.param())));
values.add(dbValue);
valueSQLTypes.add(_typeHelper.getSQLType(value));
LOGGER.info(TABLE_NAME_PREFIX + currentTableIndex + "." + columnName + " is " + dbValue);
}
}
return result;
}
use of org.sql.generation.api.grammar.builders.booleans.BooleanBuilder in project qi4j-sdk by Qi4j.
the class AbstractSQLQuerying method constructQueryForPredicate.
protected QuerySpecification constructQueryForPredicate(//
Specification<Composite> predicate, //
PropertyFunction<?> propRef, //
TraversedAssoOrManyAssoRef assoRef, //
Boolean includeLastAssoPathTable, //
Boolean negationActive, //
SQLVendor vendor, //
org.sql.generation.api.grammar.booleans.BooleanExpression entityTypeCondition, //
WhereClauseProcessor whereClauseGenerator) {
Integer startingIndex = 0;
TableReferenceFactory t = vendor.getTableReferenceFactory();
QuerySpecificationBuilder builder = this.getBuilderForPredicate(vendor, TABLE_NAME_PREFIX + startingIndex);
TableReferenceBuilder from = t.tableBuilder(t.table(t.tableName(this._state.schemaName().get(), DBNames.ENTITY_TABLE_NAME), t.tableAlias(TABLE_NAME_PREFIX + startingIndex)));
this.addTypeJoin(vendor, from, startingIndex);
Integer lastTableIndex = null;
JoinType joinStyle = this.getTableJoinStyle(predicate, negationActive);
if (propRef == null && assoRef != null && assoRef._hasRefs) {
lastTableIndex = this.traverseAssociationPath(assoRef, startingIndex, startingIndex + 1, vendor, from, joinStyle, includeLastAssoPathTable);
} else if (assoRef == null || !assoRef._hasRefs) {
lastTableIndex = this.traversePropertyPath(propRef, startingIndex, startingIndex + 1, vendor, from, joinStyle);
} else {
throw new InternalError("Can not have both property reference and association reference (non-)nulls [propRef=" + propRef + ", assoRef=" + assoRef + ", predicate=" + predicate + "].");
}
builder.getFrom().addTableReferences(from);
BooleanBuilder afterWhere = vendor.getBooleanFactory().booleanBuilder();
whereClauseGenerator.processWhereClause(builder, afterWhere, joinStyle, startingIndex, lastTableIndex);
BooleanBuilder where = builder.getWhere();
if (negationActive) {
where.not();
}
where.and(afterWhere.createExpression());
where.and(entityTypeCondition);
builder.trimGroupBy();
return builder.createExpression();
}
Aggregations