Mi sono recentemente scontrato con un problema apparentemente banale durante la realizzazione di una ricerca custom per un'applicazione Webtop-based.
La problematica era realizzare, tramite l'interfaccia IDfQueryBuilder, una query DQL del tipo:
SELECT *
FROM my_document
WHERE ANY (attr1 = ? AND attr2 = ?);
Entrambi gli attributi attr1 e attr2 sono di tipo repeating e devono essere racchiusi all'interno delle parentesti perchè mi serve fare una ricerca posizionale sui valori degli attributi, ossia una cosa del tipo:
attr1[0]=? AND attr2[0]=?
attr1[1]=? AND attr2[1]=?
attr1[2]=? AND attr2[2]=?
...e così via
Peccato che IDfQueryBuilder non consenta di creare un'espressione composta di quel tipo, ma consente solamente le 2 parti separate:
SELECT *
FROM my_document
WHERE ANY attr1 = ? AND ANY attr2 = ?;
Ecco quindi come fare a risolvere il problema.
Innanzitutto, nella classe Java che prepara la ricerca (il metodo buildQuery per intenderci) è necessario aggiungere le 2 espressioni di ricerca come se gli attributi NON fossero repeating:
IDfQueryBuilder qb = ...
IDfExpressionSet set = qb.getRootExpressionSet();
set.addSimpleAttrExpression("attr1", IDfValue.DF_STRING,
IDfSimpleAttrExpression.SEARCH_OP_EQUAL,
true, false, "valore");
set.addSimpleAttrExpression("attr2", IDfValue.DF_STRING,
IDfSimpleAttrExpression.SEARCH_OP_EQUAL,
true, false, "valore");
Dopodichè è necessario modificare il file dfc-dqlhints.xml al fine di forzare la ricerca ad utilizzare la DQL hint ROW_BASED che consente di effettuare una ricerca su attributi repeating multipli senza specificare la clausola ANY.
<Rule>
<Condition>
<From>
<Type>my_document</Type>
</From>
<Where condition="all">
<Attribute>attr1</Attribute>
<Attribute>attr2</Attribute>
</Where>
</Condition>
<DQLHint>ENABLE(ROW_BASED)</DQLHint>
</Rule>
Questa nuova rule da aggiungere ha il significato: per ogni query fatta sul tipo my_document che includa entrambi gli attributi attr1 e attr2, utilizzare la DQL hint ROW_BASED.
Ecco quindi che la query DQL che viene eseguita dal sistema sarà:
SELECT *
FROM my_document
WHERE attr1 = ? AND attr2 = ?
ENABLE(ROW_BASED);
Enjoy!