use of com.servoy.j2db.query.CompareCondition 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.CompareCondition in project servoy-client by Servoy.
the class SQLGenerator method createAggregateSelect.
public static QuerySelect createAggregateSelect(QuerySelect sqlSelect, Collection<QuerySelect> aggregates, List<Column> pkColumns) {
QuerySelect selectClone = deepClone(sqlSelect);
selectClone.clearSorts();
selectClone.setDistinct(false);
selectClone.setColumns(null);
selectClone.removeUnusedJoins(true);
QuerySelect aggregateSqlSelect;
if (selectClone.getJoins() == null) {
// simple case, no joins
// Select count(pk) from main where <condition>
aggregateSqlSelect = selectClone;
} else {
// we have joins, change to an exists-query to make the aggregates correct, otherwise duplicate records
// in the main table cause incorrect aggregate values
// Select count(pk) from main main1 where exists (select 1 from main main2 join detail on detail.FK = main2.FK where main1.PK = main2.PK and <condition>)
QuerySelect innerSelect = selectClone;
ArrayList<IQuerySelectValue> innerColumns = new ArrayList<IQuerySelectValue>();
innerColumns.add(new QueryColumnValue(Integer.valueOf(1), null, true));
innerSelect.setColumns(innerColumns);
BaseQueryTable innerTable = innerSelect.getTable();
QueryTable outerTable = new QueryTable(innerTable.getName(), innerTable.getDataSource(), innerTable.getCatalogName(), innerTable.getSchemaName());
aggregateSqlSelect = new QuerySelect(outerTable);
for (Column column : pkColumns) {
// $NON-NLS-1$
innerSelect.addCondition(// $NON-NLS-1$
"EXISTS", new CompareCondition(IBaseSQLCondition.EQUALS_OPERATOR, column.queryColumn(innerTable), column.queryColumn(outerTable)));
}
// $NON-NLS-1$
aggregateSqlSelect.addCondition("EXISTS", new ExistsCondition(innerSelect, true));
}
ArrayList<IQuerySelectValue> columns = new ArrayList<IQuerySelectValue>();
for (QuerySelect aggregate : aggregates) {
columns.addAll(AbstractBaseQuery.relinkTable(aggregate.getTable(), aggregateSqlSelect.getTable(), aggregate.getColumnsClone()));
}
aggregateSqlSelect.setColumns(columns);
return aggregateSqlSelect;
}
use of com.servoy.j2db.query.CompareCondition in project servoy-client by Servoy.
the class ViewFoundSet method doSave.
int doSave(ViewRecord record) {
int retCode = ISaveConstants.STOPPED;
List<ViewRecord> toSave = new ArrayList<>();
if (record == null) {
toSave.addAll(editedRecords);
} else {
if (record.isEditing())
toSave.add(record);
}
if (toSave.size() > 0) {
ArrayList<ViewRecord> processedRecords = new ArrayList<ViewRecord>();
try {
boolean previousRefresh = refresh;
String serverName = DataSourceUtils.getDataSourceServerName(select.getTable().getDataSource());
String transaction_id = manager.getTransactionID(serverName);
HashMap<SQLStatement, ViewRecord> statementToRecord = new HashMap<>();
List<SQLStatement> statements = new ArrayList<>();
for (ViewRecord rec : toSave) {
Map<String, Object> changes = rec.getChanges();
// directly just remove it from the edited records if we try to save it.
editedRecords.remove(rec);
if (changes == null)
continue;
Map<BaseQueryTable, Map<QueryColumn, Object>> tableToChanges = new IdentityHashMap<>();
columnNames.forEach((selectValue, name) -> {
if (changes.containsKey(name)) {
QueryColumn realColumn = select.getRealColumn(selectValue).orElseThrow(() -> {
RuntimeException ex = new RuntimeException("Can't save " + rec + " for changed values " + changes + " because table for column '" + name + "' cannot be found");
rec.setLastException(ex);
if (!failedRecords.contains(rec))
failedRecords.add(rec);
return ex;
});
BaseQueryTable table = realColumn.getTable();
Map<QueryColumn, Object> map = tableToChanges.get(table);
if (map == null) {
map = new HashMap<>();
tableToChanges.put(table, map);
}
map.put(realColumn, rec.getValue(name));
}
});
tableToChanges.forEach((table, changesMap) -> {
List<IQuerySelectValue> pkColumns = pkColumnsForTable.get(table);
if (pkColumns == null) {
RuntimeException ex = new RuntimeException("Can't save " + rec + " for changed values " + changes + " because there are no pk's found for table with changes " + table.getAlias() != null ? table.getAlias() : table.getName());
rec.setLastException(ex);
if (!failedRecords.contains(rec))
failedRecords.add(rec);
throw ex;
}
int counter = 0;
Object[] pk = new Object[pkColumns.size()];
QueryUpdate update = new QueryUpdate(table);
IQuerySelectValue[] queryPks = null;
try {
RowManager rowManager = manager.getRowManager(table.getDataSource());
if (rowManager != null) {
queryPks = getOrderedPkColumns(pkColumns, rowManager.getSQLSheet().getPKColumnDataProvidersAsArray());
}
} catch (Exception ex) {
Debug.error(ex);
}
if (queryPks == null)
queryPks = pkColumns.toArray(new IQuerySelectValue[0]);
for (IQuerySelectValue pkColumn : queryPks) {
Object pkValue = rec.getValue(columnNames.get(pkColumn));
update.addCondition(new CompareCondition(IBaseSQLCondition.EQUALS_OPERATOR, pkColumn, pkValue));
pk[counter++] = pkValue;
}
IDataSet pks = new BufferedDataSet();
pks.addRow(pk);
counter = 0;
String[] changedColumns = new String[changes.size()];
for (Entry<QueryColumn, Object> entry : changesMap.entrySet()) {
QueryColumn column = entry.getKey();
update.addValue(column, entry.getValue());
changedColumns[counter++] = column.getName();
}
SQLStatement statement = new SQLStatement(ISQLActionTypes.UPDATE_ACTION, serverName, table.getName(), pks, transaction_id, update, manager.getTableFilterParams(serverName, update));
statement.setChangedColumns(changedColumns);
statement.setExpectedUpdateCount(1);
statements.add(statement);
statementToRecord.put(statement, rec);
});
JSRecordMarkers validateObject = validate(rec);
if (validateObject != null && validateObject.isHasErrors()) {
Object[] genericExceptions = validateObject.getGenericExceptions();
if (genericExceptions.length > 0) {
rec.setLastException((Exception) genericExceptions[0]);
}
if (!failedRecords.contains(rec)) {
failedRecords.add(rec);
retCode = ISaveConstants.SAVE_FAILED;
}
}
if (!failedRecords.contains(rec)) {
processedRecords.add(rec);
}
}
if (// if this is a save all call we don't save if we have failed records
toSave.size() > 1 && failedRecords.isEmpty() || // if this is a single record save, we just check if it is failed or not
toSave.size() == 1 && !failedRecords.contains(record)) {
Object[] updateResult = manager.getApplication().getDataServer().performUpdates(manager.getApplication().getClientID(), statements.toArray(new SQLStatement[statements.size()]));
for (int i = 0; i < updateResult.length; i++) {
// i of the updateResults should be the same for the statements;
ViewRecord rec = statementToRecord.remove(statements.get(i));
Object o = updateResult[i];
if (o instanceof Exception) {
// something went wrong
failedRecords.add(rec);
rec.setLastException((Exception) o);
retCode = ISaveConstants.SAVE_FAILED;
} else if (!statementToRecord.values().contains(rec) && !failedRecords.contains(rec)) {
rec.clearChanges();
}
}
for (SQLStatement statement : statements) {
manager.notifyDataChange(DataSourceUtils.createDBTableDataSource(statement.getServerName(), statement.getTableName()), statement.getPKsRow(0), ISQLActionTypes.UPDATE_ACTION, statement.getChangedColumns());
}
// do a load but only if there are listeners
if (previousRefresh && shouldRefresh() && foundSetEventListeners.size() > 0) {
loadAllRecordsImpl();
}
}
} catch (ServoyException | RemoteException e) {
Debug.error(e);
} finally {
if (!failedRecords.isEmpty()) {
processedRecords.stream().forEachOrdered(editedRecords::add);
}
}
}
return retCode;
}
use of com.servoy.j2db.query.CompareCondition in project servoy-client by Servoy.
the class I18NUtil method loadSortedMessagesFromRepository.
public static TreeMap<String, MessageEntry> loadSortedMessagesFromRepository(IRepository repository, IDataServer dataServer, String clientID, String i18NServerName, String i18NTableName, String filterName, String[] filterValue, IFoundSetManagerInternal fm) throws Exception {
TreeMap<String, MessageEntry> sortedMessages = new TreeMap<String, MessageEntry>();
IServer i18NServer = repository.getServer(i18NServerName);
if (i18NServer != null) {
Table i18NTable = (Table) i18NServer.getTable(i18NTableName);
if (i18NTable != null) {
QueryTable messagesTable = new QueryTable(i18NTable.getSQLName(), i18NTable.getDataSource(), i18NTable.getCatalog(), i18NTable.getSchema());
QuerySelect sql = new QuerySelect(messagesTable);
QueryColumn msgLang = new QueryColumn(messagesTable, -1, "message_language", Types.VARCHAR, 150, 0, null, 0);
QueryColumn msgKey = new QueryColumn(messagesTable, -1, "message_key", Types.VARCHAR, 150, 0, null, 0);
QueryColumn msgVal = new QueryColumn(messagesTable, -1, "message_value", Types.VARCHAR, 2000, 0, null, 0);
sql.addColumn(msgLang);
sql.addColumn(msgKey);
sql.addColumn(msgVal);
// Filter to only include records with the default (null) value for columns flagged as Tenant column
for (Column column : i18NTable.getTenantColumns()) {
QueryColumn tenantColumn = new QueryColumn(messagesTable, column.getID(), column.getSQLName(), column.getType(), column.getLength(), column.getScale(), null, column.getFlags());
CompareCondition cc = new CompareCondition(IBaseSQLCondition.ISNULL_OPERATOR, tenantColumn, null);
sql.addCondition("_svy_tenant_id_filter_" + column.getName(), cc);
}
if (filterName != null) {
Column filterColumn = i18NTable.getColumn(filterName);
if (filterColumn != null && filterValue != null && filterValue.length > 0) {
QueryColumn columnFilter = new QueryColumn(messagesTable, filterColumn.getID(), filterColumn.getSQLName(), filterColumn.getType(), filterColumn.getLength(), filterColumn.getScale(), null, filterColumn.getFlags());
CompareCondition cc = new CompareCondition(IBaseSQLCondition.EQUALS_OPERATOR, columnFilter, new QueryColumnValue(filterValue[0], null));
// $NON-NLS-1$
sql.addCondition("FILTER", cc);
}
}
sql.addSort(new QuerySort(msgLang, true, SortOptions.NONE));
sql.addSort(new QuerySort(msgKey, true, SortOptions.NONE));
IDataSet set = dataServer.performQuery(clientID, i18NServerName, null, sql, null, fm != null ? fm.getTableFilterParams(i18NServerName, sql) : null, false, 0, Integer.MAX_VALUE, IDataServer.MESSAGES_QUERY);
int rowCount = set.getRowCount();
if (rowCount > 0) {
for (int i = 0; i < rowCount; i++) {
Object[] row = set.getRow(i);
MessageEntry messageEntry = new MessageEntry((String) row[0], (String) row[1], (String) row[2]);
sortedMessages.put(messageEntry.getLanguageKey(), messageEntry);
}
}
}
}
return sortedMessages;
}
use of com.servoy.j2db.query.CompareCondition in project servoy-client by Servoy.
the class I18NUtil method writeMessagesToRepository.
public static void writeMessagesToRepository(String i18NServerName, String i18NTableName, IRepository repository, IDataServer dataServer, String clientID, TreeMap<String, MessageEntry> messages, boolean noUpdates, boolean noRemoves, TreeMap<String, MessageEntry> remoteMessages, String filterName, String[] filterValue, IFoundSetManagerInternal fm) throws Exception {
// get remote messages snapshot
if (remoteMessages == null)
remoteMessages = loadSortedMessagesFromRepository(repository, dataServer, clientID, i18NServerName, i18NTableName, filterName, filterValue, fm);
if (remoteMessages != null) {
IServer i18NServer = repository.getServer(i18NServerName);
Table i18NTable = null;
if (i18NServer != null) {
i18NTable = (Table) i18NServer.getTable(i18NTableName);
}
if (i18NTable != null) {
// runtime exception when no ident columns
Column pkColumn = i18NTable.getRowIdentColumns().get(0);
QueryTable messagesTable = new QueryTable(i18NTable.getSQLName(), i18NTable.getDataSource(), i18NTable.getCatalog(), i18NTable.getSchema());
QueryColumn pkCol = pkColumn.queryColumn(messagesTable);
QueryColumn msgLang = new QueryColumn(messagesTable, -1, "message_language", Types.VARCHAR, 150, 0, null, 0);
QueryColumn msgKey = new QueryColumn(messagesTable, -1, "message_key", Types.VARCHAR, 150, 0, null, 0);
QueryColumn msgVal = new QueryColumn(messagesTable, -1, "message_value", Types.VARCHAR, 2000, 0, null, 0);
ArrayList<SQLStatement> updateStatements = new ArrayList<SQLStatement>();
// go thorough messages, update exiting, add news to remote
// in case we need to insert a record, we must know if it is database managed or servoy managed
boolean logIdIsServoyManaged = false;
ColumnInfo ci = pkColumn.getColumnInfo();
if (ci != null) {
int autoEnterType = ci.getAutoEnterType();
int autoEnterSubType = ci.getAutoEnterSubType();
logIdIsServoyManaged = (autoEnterType == ColumnInfo.SEQUENCE_AUTO_ENTER) && (autoEnterSubType != ColumnInfo.NO_SEQUENCE_SELECTED) && (autoEnterSubType != ColumnInfo.DATABASE_IDENTITY);
}
List<Column> tenantColumns = i18NTable.getTenantColumns();
Iterator<Map.Entry<String, MessageEntry>> messagesIte = messages.entrySet().iterator();
Map.Entry<String, MessageEntry> messageEntry;
while (messagesIte.hasNext()) {
messageEntry = messagesIte.next();
String key = messageEntry.getKey();
String value = messageEntry.getValue().getValue();
String lang = messageEntry.getValue().getLanguage();
if (lang.equals(""))
lang = null;
String messageKey = messageEntry.getValue().getKey();
if (// insert
!remoteMessages.containsKey(key)) {
QueryInsert insert = new QueryInsert(messagesTable);
QueryColumn[] insertColumns = null;
Object[] insertColumnValues = null;
if (logIdIsServoyManaged) {
Object messageId = dataServer.getNextSequence(i18NServerName, i18NTableName, pkColumn.getName(), -1, i18NServerName);
if (lang == null) {
insertColumns = new QueryColumn[] { pkCol, msgKey, msgVal };
insertColumnValues = new Object[] { messageId, messageKey, value };
} else {
insertColumns = new QueryColumn[] { pkCol, msgKey, msgLang, msgVal };
insertColumnValues = new Object[] { messageId, messageKey, lang, value };
}
} else {
if (lang == null) {
insertColumns = new QueryColumn[] { msgKey, msgVal };
insertColumnValues = new Object[] { messageKey, value };
} else {
insertColumns = new QueryColumn[] { msgKey, msgLang, msgVal };
insertColumnValues = new Object[] { messageKey, lang, value };
}
}
Column filterColumn = i18NTable.getColumn(filterName);
if (filterColumn != null && filterValue != null && filterValue.length > 0) {
insertColumns = Utils.arrayAdd(insertColumns, filterColumn.queryColumn(messagesTable), true);
insertColumnValues = Utils.arrayAdd(insertColumnValues, filterValue[0], true);
}
insert.setColumnValues(insertColumns, insertColumnValues);
updateStatements.add(new SQLStatement(ISQLActionTypes.INSERT_ACTION, i18NServerName, i18NTableName, null, null, insert, null));
} else if (// update
!remoteMessages.get(key).getValue().equals(value) && !noUpdates) {
QueryUpdate update = new QueryUpdate(messagesTable);
update.addValue(msgVal, value);
update.addCondition(new CompareCondition(IBaseSQLCondition.EQUALS_OPERATOR, msgKey, messageKey));
update.addCondition(new CompareCondition(IBaseSQLCondition.EQUALS_OPERATOR, msgLang, lang));
if (filterName != null) {
Column filterColumn = i18NTable.getColumn(filterName);
if (filterColumn != null && filterValue != null && filterValue.length > 0) {
QueryColumn columnFilter = filterColumn.queryColumn(messagesTable);
CompareCondition cc = new CompareCondition(IBaseSQLCondition.EQUALS_OPERATOR, columnFilter, new QueryColumnValue(filterValue[0], null));
// $NON-NLS-1$
update.addCondition("FILTER", cc);
}
}
// Add condition to update only records having the default tenant value (null)
for (Column column : tenantColumns) {
QueryColumn tenantColumn = column.queryColumn(messagesTable);
CompareCondition cc = new CompareCondition(IBaseSQLCondition.ISNULL_OPERATOR, tenantColumn, null);
update.addCondition(cc);
}
updateStatements.add(new SQLStatement(ISQLActionTypes.UPDATE_ACTION, i18NServerName, i18NTableName, null, null, update, fm != null ? fm.getTableFilterParams(i18NServerName, update) : null));
}
}
if (!noRemoves) {
// go thorough remote, remove if not existing locally
Iterator<Map.Entry<String, MessageEntry>> remoteMessagesIte = remoteMessages.entrySet().iterator();
Map.Entry<String, MessageEntry> remoteMessageEntry;
while (remoteMessagesIte.hasNext()) {
remoteMessageEntry = remoteMessagesIte.next();
String key = remoteMessageEntry.getKey();
if (// delete
!messages.containsKey(key)) {
String lang = remoteMessageEntry.getValue().getLanguage();
if (lang.equals(""))
lang = null;
String messageKey = remoteMessageEntry.getValue().getKey();
QueryDelete delete = new QueryDelete(messagesTable);
delete.addCondition(new CompareCondition(IBaseSQLCondition.EQUALS_OPERATOR, msgKey, messageKey));
delete.addCondition(new CompareCondition(IBaseSQLCondition.EQUALS_OPERATOR, msgLang, lang));
if (filterName != null) {
Column filterColumn = i18NTable.getColumn(filterName);
if (filterColumn != null && filterValue != null && filterValue.length > 0) {
QueryColumn columnFilter = filterColumn.queryColumn(messagesTable);
CompareCondition cc = new CompareCondition(IBaseSQLCondition.EQUALS_OPERATOR, columnFilter, new QueryColumnValue(filterValue[0], null));
delete.addCondition(cc);
}
}
// Add condition to remove only records having the default tenant value (null)
for (Column column : tenantColumns) {
QueryColumn tenantColumn = column.queryColumn(messagesTable);
CompareCondition cc = new CompareCondition(IBaseSQLCondition.ISNULL_OPERATOR, tenantColumn, null);
delete.addCondition(cc);
}
updateStatements.add(new SQLStatement(ISQLActionTypes.DELETE_ACTION, i18NServerName, i18NTableName, null, null, delete, fm != null ? fm.getTableFilterParams(i18NServerName, delete) : null));
}
}
}
for (SQLStatement st : updateStatements) {
st.setDataType(ISQLStatement.I18N_DATA_TYPE);
}
dataServer.performUpdates(clientID, updateStatements.toArray(new ISQLStatement[updateStatements.size()]));
}
}
}
Aggregations