use of com.servoy.j2db.query.ISQLCondition in project servoy-client by Servoy.
the class FoundSet method copy.
public IFoundSetInternal copy(boolean unrelate) throws ServoyException {
// $NON-NLS-1$
if (findMode)
throw new RuntimeException("Foundsets in findmode can't be duplicated");
if (sheet.getTable() == null)
return this;
FoundSet fs = (FoundSet) fsm.getNewFoundSet(sheet.getTable(), creationSqlSelect, lastSortColumns);
if (foundSetFilters != null) {
fs.foundSetFilters = new ArrayList<TableFilter>(foundSetFilters);
}
synchronized (pksAndRecords) {
QuerySelect fs_sqlSelect = pksAndRecords.getQuerySelectForModification();
if (unrelate) {
// clear the relation condition, new finds should also retrieve records outside the relation
ISQLCondition relationCondition = fs_sqlSelect.getCondition(SQLGenerator.CONDITION_RELATION);
fs_sqlSelect.clearCondition(SQLGenerator.CONDITION_RELATION);
fs.creationSqlSelect.clearCondition(SQLGenerator.CONDITION_RELATION);
if (relationCondition != null) {
// store old relation condition as search for extend/reduce-search
fs_sqlSelect.addCondition(SQLGenerator.CONDITION_SEARCH, relationCondition);
}
} else {
fs.sheet = sheet;
fs.relationName = relationName;
}
fs.pksAndRecords.setPksAndQuery(new BufferedDataSet(pksAndRecords.getPks()), pksAndRecords.getDbIndexLastPk(), fs_sqlSelect);
}
fs.initialized = initialized;
if (omittedPKs != null)
fs.omittedPKs = new BufferedDataSet(omittedPKs.getColumnNames(), omittedPKs.getColumnTypes(), omittedPKs.getRows());
SafeArrayList<IRecordInternal> cachedRecords = pksAndRecords.getCachedRecords();
SafeArrayList<IRecordInternal> fsCachedRecords = fs.pksAndRecords.getCachedRecords();
for (int i = 0; i < cachedRecords.size(); i++) {
IRecordInternal record = cachedRecords.get(i);
if (record != null && !record.existInDataSource()) {
fsCachedRecords.set(i, new Record(fs, record.getRawData()));
}
}
fs.setMultiSelectInternal(isMultiSelect());
if (isMultiSelect()) {
int[] selectedIndexes = getSelectedIndexes();
if (selectedIndexes != null && selectedIndexes.length > 0)
fs.setSelectedIndexes(selectedIndexes);
else
fs.setSelectedIndex(getSelectedIndex());
} else
fs.setSelectedIndex(getSelectedIndex());
return fs;
}
use of com.servoy.j2db.query.ISQLCondition in project servoy-client by Servoy.
the class SQLGenerator method getPKSelectSqlSelect.
/*
* _____________________________________________________________ The methods below belong to this class
*/
// SQL pk(s) select for foundset,concatenating those strings will always deliver a executable SQL
// Note: removeUnusedJoins must be false when the resulting query is changed afterwards (like adding columns)
QuerySelect getPKSelectSqlSelect(IGlobalValueEntry provider, Table table, QuerySelect oldSQLQuery, List<IRecordInternal> findStates, boolean reduce, IDataSet omitPKs, List<SortColumn> orderByFields, boolean removeUnusedJoins) throws ServoyException {
if (table == null) {
throw new RepositoryException(ServoyException.InternalCodes.TABLE_NOT_FOUND);
}
QuerySelect retval;
if (oldSQLQuery != null) {
retval = deepClone(oldSQLQuery);
retval.setGroupBy(null);
// will be generated based on foundset sorting
if (orderByFields != null)
retval.clearSorts();
// remove all servoy conditions, except filter, search and relation
for (String conditionName : retval.getConditionNames()) {
if (conditionName.startsWith(SERVOY_CONDITION_PREFIX) && !(CONDITION_FILTER.equals(conditionName) || CONDITION_SEARCH.equals(conditionName) || CONDITION_RELATION.equals(conditionName))) {
retval.setCondition(conditionName, null);
}
}
} else {
retval = new QuerySelect(new QueryTable(table.getSQLName(), table.getDataSource(), table.getCatalog(), table.getSchema()));
}
// Example:-select pk1,pk2 from tablename1 where ((fieldname1 like '%abcd%') or ((fieldname2 like '%xyz%')) (retrieve max 200 rows)
ArrayList<IQuerySelectValue> pkQueryColumns = new ArrayList<IQuerySelectValue>(3);
ArrayList<Column> pkColumns = new ArrayList<Column>(3);
// getPrimaryKeys from table
Iterator<Column> pks = table.getRowIdentColumns().iterator();
// make select
if (!pks.hasNext()) {
throw new RepositoryException(ServoyException.InternalCodes.PRIMARY_KEY_NOT_FOUND, new Object[] { table.getName() });
}
while (pks.hasNext()) {
Column column = pks.next();
pkColumns.add(column);
pkQueryColumns.add(column.queryColumn(retval.getTable()));
}
retval.setColumns(pkQueryColumns);
if (omitPKs != null && omitPKs.getRowCount() != 0) {
// omit is rebuild each time
retval.setCondition(CONDITION_OMIT, createSetConditionFromPKs(IBaseSQLCondition.NOT_OPERATOR, pkQueryColumns.toArray(new QueryColumn[pkQueryColumns.size()]), pkColumns, omitPKs));
} else if (oldSQLQuery != null) {
retval.setCondition(CONDITION_OMIT, oldSQLQuery.getConditionClone(CONDITION_OMIT));
}
if (// new
findStates != null && findStates.size() != 0) {
ISQLCondition moreWhere = null;
for (IRecordInternal obj : findStates) {
if (obj instanceof FindState) {
moreWhere = OrCondition.or(moreWhere, createConditionFromFindState((FindState) obj, retval, provider, pkQueryColumns));
}
}
if (moreWhere != null) {
if (reduce) {
retval.addCondition(CONDITION_SEARCH, moreWhere);
} else {
retval.addConditionOr(CONDITION_SEARCH, moreWhere);
}
if (retval.getJoins() != null) {
// check if the search condition has an or-condition
final boolean[] hasOr = { false };
retval.getCondition(CONDITION_SEARCH).acceptVisitor(new IVisitor() {
public Object visit(Object o) {
if (o instanceof OrCondition && ((OrCondition) o).getConditions().size() > 1) {
hasOr[0] = true;
return new VisitorResult(o, false);
}
return o;
}
});
if (hasOr[0]) {
// override join type to left outer join, a related OR-search should not make the result set smaller
for (ISQLJoin join : retval.getJoins()) {
if (join instanceof QueryJoin && ((QueryJoin) join).getJoinType() == IQueryConstants.INNER_JOIN) {
((QueryJoin) join).setJoinType(IQueryConstants.LEFT_OUTER_JOIN);
}
}
}
}
}
}
// make orderby
if (orderByFields != null || retval.getSorts() == null) {
List<SortColumn> orderBy = orderByFields == null ? new ArrayList<SortColumn>(3) : orderByFields;
if (orderBy.size() == 0) {
for (Column pkColumn : pkColumns) {
orderBy.add(new SortColumn(pkColumn));
}
}
addSorts(retval, retval.getTable(), provider, table, orderBy, true, false);
}
if (removeUnusedJoins) {
// remove unneeded joins, some may have been added because of a previous sort and are no longer needed.
retval.removeUnusedJoins(false);
}
// 1 do not remove sort or groupby test, will cause invalid queries
// 1 this one causes error and can not be fixed,
// 1 if (joinswherepart.length() != 0 && !sortIsRelated && groupbyKeyword == STRING_EMPTY && table.getPrimaryKeyCount() == 1)
// 1 sql select distinct(s_contacts.contactsid) from s_contacts,s_companies where s_contacts.company_id = s_companies.company_id order by s_contacts.surname ERROR: For SELECT DISTINCT, ORDER BY expressions must appear in target list
// retval may have set distinct and plainPKSelect flag based on previous sort columns, make sure to reset first
retval.setDistinct(false);
retval.setPlainPKSelect(false);
if (// if joined pks comes back multiple times
retval.getJoins() != null && retval.getColumns().size() == 1 && isDistinctAllowed(retval.getColumns(), retval.getSorts())) {
retval.setDistinct(true);
} else if (// plain pk select
retval.getJoins() == null && retval.getColumns().size() == pkColumns.size()) {
retval.setPlainPKSelect(true);
}
return retval;
}
use of com.servoy.j2db.query.ISQLCondition in project servoy-client by Servoy.
the class SQLGenerator method createConditionFromFindState.
private ISQLCondition createConditionFromFindState(FindState s, QuerySelect sqlSelect, IGlobalValueEntry provider, List<IQuerySelectValue> pkQueryColumns) throws RepositoryException {
ISQLCondition and = null;
List<RelatedFindState> relatedFindStates = s.createFindStateJoins(sqlSelect, Collections.<IRelation>emptyList(), sqlSelect.getTable(), provider);
for (int i = 0; relatedFindStates != null && i < relatedFindStates.size(); i++) {
RelatedFindState rfs = relatedFindStates.get(i);
FindState state = rfs.getFindState();
BaseQueryTable columnTable = rfs.getPrimaryTable();
SQLSheet sheet = state.getParentFoundSet().getSQLSheet();
Table table = sheet.getTable();
Iterator<Map.Entry<String, Object>> it = state.getColumnData().entrySet().iterator();
while (it.hasNext()) {
Map.Entry<String, Object> elem = it.next();
final String dataProviderID = elem.getKey();
Object raw = elem.getValue();
if (raw == null)
continue;
int dataProviderType = -1;
ConverterInfo columnConverterInfo = null;
IColumnConverter columnConverter = null;
IQuerySelectValue qCol = null;
IColumn c = table.getColumn(dataProviderID);
if (c != null) {
dataProviderType = c.getDataProviderType();
columnConverterInfo = sheet.getColumnConverterInfo(dataProviderID);
if (columnConverterInfo != null) {
columnConverter = application.getFoundSetManager().getColumnConverterManager().getConverter(columnConverterInfo.converterName);
if (columnConverter instanceof ITypedColumnConverter) {
int convType = ((ITypedColumnConverter) columnConverter).getToObjectType(columnConverterInfo.props);
if (convType != Integer.MAX_VALUE) {
dataProviderType = mapToDefaultType(convType);
}
}
}
// a column
qCol = ((Column) c).queryColumn(columnTable);
} else {
// not a column, check for aggregates
Iterator<AggregateVariable> aggregateVariables = application.getFlattenedSolution().getAggregateVariables(sheet.getTable(), false);
while (c == null && aggregateVariables.hasNext()) {
AggregateVariable agg = aggregateVariables.next();
if (dataProviderID.equals(agg.getDataProviderID())) {
// found aggregate
c = agg;
}
}
if (c != null) {
dataProviderType = c.getDataProviderType();
Map<String, QuerySelect> aggregates = sheet.getAggregates();
if (aggregates != null) {
QuerySelect aggregateSelect = aggregates.get(dataProviderID);
if (aggregateSelect != null) {
qCol = ((List<IQuerySelectValue>) AbstractBaseQuery.relinkTable(aggregateSelect.getTable(), columnTable, aggregateSelect.getColumnsClone())).get(0);
}
}
}
}
if (qCol == null) {
// not a column and not an aggregate
// $NON-NLS-1$ //$NON-NLS-2$
Debug.log("Ignoring search on unknown/unsupported data provider '" + dataProviderID + "'");
continue;
}
ParsedFormat format = state.getFormat(dataProviderID);
String formatString = null;
if (format != null) {
formatString = format.getEditFormat();
if (formatString == null) {
formatString = format.getDisplayFormat();
}
}
if (Utils.stringIsEmpty(formatString)) {
formatString = TagResolver.getDefaultFormatForType(application, dataProviderType);
}
ISQLCondition or = null;
if (raw.getClass().isArray()) {
int length = Array.getLength(raw);
Object[] elements = new Object[length];
for (int e = 0; e < length; e++) {
Object obj = Array.get(raw, e);
if (obj instanceof Wrapper) {
obj = ((Wrapper) obj).unwrap();
}
// Have to use getAsRightType twice here, once to parse using format (getAsType(dataProviderType, formatString))
// and once to convert for query (getAsType(c.getDataProviderType(), null))
Object converted = convertFromObject(application, columnConverter, columnConverterInfo, dataProviderID, c.getDataProviderType(), Column.getAsRightType(dataProviderType, c.getFlags(), obj, formatString, c.getLength(), null, false, false), false);
elements[e] = Column.getAsRightType(c.getDataProviderType(), c.getFlags(), converted, null, c.getLength(), null, false, false);
}
// where qCol in (e1, e2, ..., en)
or = new SetCondition(IBaseSQLCondition.EQUALS_OPERATOR, new IQuerySelectValue[] { qCol }, new Object[][] { elements }, true);
} else {
final IColumnConverter fColumnConverter = columnConverter;
final ConverterInfo fColumnConverterInfo = columnConverterInfo;
final int fDataProviderType = c.getDataProviderType();
or = (ISQLCondition) BaseSQLGenerator.parseFindExpression(QueryFactory.INSTANCE, raw, qCol, columnTable, dataProviderType, formatString, c, rfs.getRelations().size() > 0 && relatedNullSearchAddPkCondition(), new IValueConverter() {
@Override
public Object convertFromObject(Object value) {
return SQLGenerator.convertFromObject(application, fColumnConverter, fColumnConverterInfo, dataProviderID, fDataProviderType, value, false);
}
}, new ITypeConverter() {
@Override
public Object getAsRightType(int type, int flags, Object obj, int l, boolean throwOnFail) {
return Column.getAsRightType(type, flags, obj, l, throwOnFail, false);
}
@Override
public Object getAsRightType(int type, int flags, Object obj, String format, int l, boolean throwOnFail) {
return Column.getAsRightType(type, flags, obj, format, l, null, throwOnFail, false);
}
}, table.getRowIdentColumns().get(0), Debug.LOGGER);
}
if (or != null) {
ISQLCondition condition;
if (c instanceof AggregateVariable) {
condition = createExistsCondition(application.getFlattenedSolution(), sqlSelect, or, rfs.getRelations(), columnTable, provider, pkQueryColumns.toArray(new QueryColumn[pkQueryColumns.size()]));
} else {
condition = or;
}
and = AndCondition.and(and, condition);
}
}
}
return and;
}
use of com.servoy.j2db.query.ISQLCondition in project servoy-client by Servoy.
the class SQLGenerator method createTableFiltercondition.
public static QueryFilter createTableFiltercondition(BaseQueryTable qTable, Table table, DataproviderTableFilterdefinition filterdefinition) {
Column c = table.getColumn(filterdefinition.getDataprovider());
if (c == null) {
// $NON-NLS-1$ //$NON-NLS-2$ //$NON-NLS-3$
Debug.error("Could not apply filter " + filterdefinition + " on table " + table + " : column not found:" + filterdefinition.getDataprovider());
return null;
}
int op = filterdefinition.getOperator();
int maskedOp = op & IBaseSQLCondition.OPERATOR_MASK;
Object value = filterdefinition.getValue();
QueryColumn qColumn = c.queryColumn(qTable);
ISQLCondition filterWhere;
if (maskedOp == IBaseSQLCondition.EQUALS_OPERATOR || maskedOp == IBaseSQLCondition.NOT_OPERATOR || maskedOp == IBaseSQLCondition.IN_OPERATOR || maskedOp == IBaseSQLCondition.NOT_IN_OPERATOR || maskedOp == IBaseSQLCondition.GT_OPERATOR || maskedOp == IBaseSQLCondition.LT_OPERATOR || maskedOp == IBaseSQLCondition.GTE_OPERATOR || maskedOp == IBaseSQLCondition.LTE_OPERATOR) {
Object inValues;
boolean andCondition = true;
if (value instanceof List<?>) {
inValues = new Object[][] { ((List<?>) value).toArray() };
andCondition = maskedOp != IBaseSQLCondition.NOT_OPERATOR && maskedOp != IBaseSQLCondition.NOT_IN_OPERATOR;
} else if (value != null && value.getClass().isArray()) {
inValues = new Object[][] { (Object[]) value };
andCondition = maskedOp != IBaseSQLCondition.NOT_OPERATOR && maskedOp != IBaseSQLCondition.NOT_IN_OPERATOR;
} else {
if (value != null && isSelectQuery(value.toString())) {
if ((op & IBaseSQLCondition.IS_SQL_MODIFIER) == 0) {
Debug.warn("Filter is created using a custom query without using the sql-modifier, this will be removed in a future version of servoy, please use operator '" + RelationItem.getOperatorAsString(op | IBaseSQLCondition.IS_SQL_MODIFIER) + "'");
}
// add as subquery
inValues = new QueryCustomSelect(value.toString(), null);
} else {
if (value != null && (op & IBaseSQLCondition.IS_SQL_MODIFIER) != 0) {
Debug.warn("Filter has the sql-modifier, but the value is not valid sql for filters: " + SQL_QUERY_VALIDATION_MESSAGE + ":" + value);
}
inValues = new Object[][] { new Object[] { value } };
}
}
// replace values with column type value
if (inValues instanceof Object[][]) {
Object[][] array = (Object[][]) inValues;
for (int i = 0; i < array.length; i++) {
for (int j = 0; array[i] != null && j < array[i].length; j++) {
Object v = c.getAsRightType(array[i][j]);
if (v == null)
v = ValueFactory.createNullValue(c.getType());
array[i][j] = v;
}
}
}
filterWhere = new SetCondition(op, new IQuerySelectValue[] { qColumn }, inValues, andCondition);
} else if (maskedOp == IBaseSQLCondition.BETWEEN_OPERATOR || maskedOp == IBaseSQLCondition.NOT_BETWEEN_OPERATOR) {
Object op1 = null;
Object op2 = null;
if (value instanceof List<?> && ((List<?>) value).size() > 1) {
op1 = ((List<?>) value).get(0);
op2 = ((List<?>) value).get(1);
} else if (value != null && value.getClass().isArray() && ((Object[]) value).length > 1) {
op1 = ((Object[]) value)[0];
op2 = ((Object[]) value)[1];
}
op1 = c.getAsRightType(op1);
if (op1 == null)
op1 = ValueFactory.createNullValue(c.getType());
op2 = c.getAsRightType(op2);
if (op2 == null)
op2 = ValueFactory.createNullValue(c.getType());
filterWhere = new CompareCondition(op, qColumn, new Object[] { op1, op2 });
} else {
Object operand;
if (maskedOp == IBaseSQLCondition.LIKE_OPERATOR || maskedOp == IBaseSQLCondition.NOT_LIKE_OPERATOR) {
operand = value;
} else {
operand = c.getAsRightType(value);
if (operand == null)
operand = ValueFactory.createNullValue(c.getType());
}
filterWhere = new CompareCondition(op, qColumn, operand);
}
return new QueryFilter(filterWhere);
}
use of com.servoy.j2db.query.ISQLCondition in project servoy-client by Servoy.
the class QBSelect method having.
/**
* Get the having-part of the query, used to add conditions.
* The conditions added here are AND-ed.
* @sample
* var query = datasources.db.example_data.orders.createSelect();
* query.groupBy.addPk() // have to group by on pk when using having-conditions in (foundset) pk queries
* .root.having.add(query.joins.orders_to_order_details.columns.quantity.count.eq(0))
* foundset.loadRecords(query)
*/
@JSReadonlyProperty
public QBLogicalCondition having() throws RepositoryException {
if (having == null) {
ISQLCondition c = getQuery().getHaving();
if (!(c instanceof AndOrCondition)) {
getQuery().setHaving(c = AndCondition.and(c, new AndCondition()));
}
having = new QBLogicalCondition(this, this, (AndOrCondition) c);
}
return having;
}
Aggregations