use of com.servoy.j2db.query.QueryDelete in project servoy-client by Servoy.
the class MetaDataUtils method loadMetadataInTable.
public static int loadMetadataInTable(ITable table, String json) throws IOException, ServoyException, JSONException {
// parse dataset
BufferedDataSet dataSet = MetaDataUtils.deserializeTableMetaDataContents(json);
// check if all columns exist
List<String> missingColumns = null;
for (String colname : dataSet.getColumnNames()) {
if (table.getColumn(colname) == null) {
if (missingColumns == null) {
missingColumns = new ArrayList<String>();
}
missingColumns.add(colname);
}
}
if (missingColumns != null) {
StringBuilder message = new StringBuilder("Missing columns from meta data for table '").append(table.getName()).append("'").append(" in server '").append(table.getServerName()).append("' : ");
for (String name : missingColumns) {
message.append('\'').append(name).append("' ");
}
throw new RepositoryException(message.toString());
}
// delete existing data
ApplicationServerRegistry.get().getDataServer().performUpdates(ApplicationServerRegistry.get().getClientId(), new ISQLStatement[] { new //
SQLStatement(//
IDataServer.META_DATA_QUERY, //
table.getServerName(), //
table.getName(), //
null, // delete entire table
new QueryDelete(new QueryTable(table.getSQLName(), table.getDataSource(), table.getCatalog(), table.getSchema()))) });
// insert the data
ApplicationServerRegistry.get().getDataServer().insertDataSet(ApplicationServerRegistry.get().getClientId(), dataSet, table.getDataSource(), table.getServerName(), table.getName(), null, null, null, null);
return dataSet.getRowCount();
}
use of com.servoy.j2db.query.QueryDelete in project servoy-client by Servoy.
the class SQLGenerator method createTableSQL.
private SQLSheet createTableSQL(String dataSource, boolean cache) throws ServoyException {
if (dataSource == null) {
return createNoTableSQL(cache);
}
Table table = (Table) application.getFoundSetManager().getTable(dataSource);
if (table == null) {
// $NON-NLS-1$
throw new RepositoryException("Cannot create sql: table not found for data source '" + dataSource + '\'');
}
SQLSheet retval = new SQLSheet(application, table.getServerName(), table);
// never remove this line, due to recursive behaviour, register a state when immediately!
if (cache)
cachedDataSourceSQLSheets.put(dataSource, retval);
QueryTable queryTable = new QueryTable(table.getSQLName(), table.getDataSource(), table.getCatalog(), table.getSchema());
QuerySelect select = new QuerySelect(queryTable);
QueryDelete delete = new QueryDelete(queryTable);
QueryInsert insert = new QueryInsert(queryTable);
QueryUpdate update = new QueryUpdate(queryTable);
List<Column> columns = new ArrayList<Column>();
Iterator<Column> it1 = table.getColumns().iterator();
while (it1.hasNext()) {
Column c = it1.next();
ColumnInfo ci = c.getColumnInfo();
if (ci != null && ci.isExcluded()) {
continue;
}
columns.add(c);
}
List<String> requiredDataProviderIDs = new ArrayList<String>();
Iterator<Column> pks = table.getRowIdentColumns().iterator();
if (!pks.hasNext()) {
throw new RepositoryException(ServoyException.InternalCodes.PRIMARY_KEY_NOT_FOUND, new Object[] { table.getName() });
}
List<QueryColumn> pkQueryColumns = new ArrayList<QueryColumn>();
while (pks.hasNext()) {
Column column = pks.next();
if (!columns.contains(column))
columns.add(column);
requiredDataProviderIDs.add(column.getDataProviderID());
pkQueryColumns.add(column.queryColumn(queryTable));
}
Iterator<Column> it2 = columns.iterator();
select.setColumns(makeQueryColumns(it2, queryTable, insert));
SetCondition pkSelect = new SetCondition(IBaseSQLCondition.EQUALS_OPERATOR, pkQueryColumns.toArray(new QueryColumn[pkQueryColumns.size()]), new Placeholder(new TablePlaceholderKey(queryTable, PLACEHOLDER_PRIMARY_KEY)), true);
select.setCondition(CONDITION_SEARCH, pkSelect);
delete.setCondition(deepClone(pkSelect));
update.setCondition(deepClone(pkSelect));
// fill dataprovider map
List<String> dataProviderIDsDilivery = new ArrayList<String>();
for (Column col : columns) {
dataProviderIDsDilivery.add(col.getDataProviderID());
}
retval.addSelect(select, dataProviderIDsDilivery, requiredDataProviderIDs, null);
retval.addDelete(delete, requiredDataProviderIDs);
retval.addInsert(insert, dataProviderIDsDilivery);
retval.addUpdate(update, dataProviderIDsDilivery, requiredDataProviderIDs);
// related stuff
createAggregates(retval, queryTable);
return retval;
}
use of com.servoy.j2db.query.QueryDelete 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()]));
}
}
}
use of com.servoy.j2db.query.QueryDelete in project servoy-client by Servoy.
the class FoundSet method deleteAllInternal.
public void deleteAllInternal() throws ServoyException {
Table table = sheet.getTable();
if (table == null) {
return;
}
fireSelectionAdjusting();
boolean partOfBiggerDelete = false;
// does have access, does not have join to other table and doesn't have a on delete method
QuerySelect sqlSelect;
IDataSet currentPKs;
synchronized (pksAndRecords) {
sqlSelect = pksAndRecords.getQuerySelectForReading();
currentPKs = pksAndRecords.getPks();
}
if (!hasAccess(IRepository.TRACKING) && sqlSelect.getJoins() == null && !tableHasOnDeleteMethods()) {
if (!hasAccess(IRepository.DELETE)) {
throw new ApplicationException(ServoyException.NO_DELETE_ACCESS, new Object[] { table.getName() });
}
boolean hasRelationsWithDelete = false;
Iterator<Relation> it = fsm.getApplication().getFlattenedSolution().getRelations(table, true, false);
while (it.hasNext()) {
Relation element = it.next();
if ((element.getDeleteRelatedRecords() || !element.getAllowParentDeleteWhenHavingRelatedRecords()) && !element.isGlobal()) {
// $NON-NLS-1$ //$NON-NLS-2$
Debug.trace("Foundset deleted per-record because relation '" + element.getName() + "' requires some checks");
hasRelationsWithDelete = true;
break;
}
}
if (!hasRelationsWithDelete) {
getFoundSetManager().getEditRecordList().removeEditedRecords(this);
// do sql delete all at once
QueryDelete delete_sql = new QueryDelete(sqlSelect.getTable());
delete_sql.setCondition(sqlSelect.getWhereClone());
IDataSet deletePKs;
boolean allFoundsetRecordsLoaded = currentPKs != null && pksAndRecords.getCachedRecords().size() == getSize() && !hadMoreRows();
if (allFoundsetRecordsLoaded) {
// clone because this will be used in a separate thread by performUpdates while it will be altered in this one (deletes all records at the end of the method)
deletePKs = currentPKs.clone();
} else {
deletePKs = new BufferedDataSet();
deletePKs.addRow(new Object[] { ValueFactory.createTableFlushValue() });
}
String tid = fsm.getTransactionID(table.getServerName());
SQLStatement statement = new SQLStatement(ISQLActionTypes.DELETE_ACTION, table.getServerName(), table.getName(), deletePKs, tid, delete_sql, fsm.getTableFilterParams(table.getServerName(), delete_sql));
try {
Object[] results = fsm.getDataServer().performUpdates(fsm.getApplication().getClientID(), new ISQLStatement[] { statement });
for (int i = 0; results != null && i < results.length; i++) {
if (results[i] instanceof ServoyException) {
throw (ServoyException) results[i];
}
}
if (!allFoundsetRecordsLoaded) {
fsm.flushCachedDatabaseData(fsm.getDataSource(table));
}
partOfBiggerDelete = true;
} catch (ApplicationException aex) {
if (allFoundsetRecordsLoaded || aex.getErrorCode() != ServoyException.RECORD_LOCKED) {
throw aex;
}
// a record was locked by another client, try per-record
// $NON-NLS-1$
Debug.log("Could not delete all records in 1 statement (a record may be locked), trying per-record");
} catch (RemoteException e) {
throw new RepositoryException(e);
}
}
}
// Need to get all the PKs, recursive delete may not actually remove the PK from the list because it is already being deleted.
if (!partOfBiggerDelete) {
PksAndRecordsHolder pksAndRecordsCopy;
int rowCount;
synchronized (pksAndRecords) {
pksAndRecordsCopy = pksAndRecords.shallowCopy();
IDataSet pks = pksAndRecordsCopy.getPks();
rowCount = pks == null ? 0 : pks.getRowCount();
}
queryForMorePKs(pksAndRecordsCopy, rowCount, -1, false);
}
try {
for (int i = getSize() - 1; i >= 0; i--) {
deleteRecord(i, partOfBiggerDelete);
}
} finally {
int correctedSize = getCorrectedSizeForFires();
if (correctedSize > -1)
fireFoundSetEvent(0, correctedSize, FoundSetEvent.CHANGE_DELETE);
}
}
use of com.servoy.j2db.query.QueryDelete in project servoy-client by Servoy.
the class JSDatabaseManager method js_mergeRecords.
// strongly recommended to use a transaction
// currently does not support compound pks
/**
* Merge records from the same foundset, updates entire datamodel (via foreign type on columns) with destination
* record pk, deletes source record. Do use a transaction!
*
* This function is very handy in situations where duplicate data exists. It allows you to merge the two records
* and move all related records in one go. Say the source_record is "Ikea" and the combined_destination_record is "IKEA", the
* "Ikea" record is deleted and all records related to it (think of contacts and orders, for instance) will be related
* to the "IKEA" record.
*
* The function takes an optional array of column names. If provided, the data in the named columns will be copied
* from source_record to combined_destination_record.
*
* Note that it is essential for both records to originate from the same foundset, as shown in the sample code.
*
* @sample databaseManager.mergeRecords(foundset.getRecord(1),foundset.getRecord(2));
*
* @param sourceRecord The source JSRecord to copy from.
* @param combinedDestinationRecord The target/destination JSRecord to copy into.
* @param columnNames The column names array that should be copied.
*
* @return true if the records could me merged.
*/
public boolean js_mergeRecords(IRecordInternal sourceRecord, IRecordInternal combinedDestinationRecord, String[] columnNames) throws ServoyException {
checkAuthorized();
if (sourceRecord != null && combinedDestinationRecord != null) {
FoundSetManager fsm = (FoundSetManager) application.getFoundSetManager();
try {
if (sourceRecord.getParentFoundSet() != combinedDestinationRecord.getParentFoundSet()) {
return false;
}
Table mainTable = (Table) combinedDestinationRecord.getParentFoundSet().getTable();
String mainTableForeignType = mainTable.getName();
String transaction_id = fsm.getTransactionID(mainTable.getServerName());
Object sourceRecordPK = null;
Object combinedDestinationRecordPK = null;
Column pkc = null;
Iterator<Column> pk_it = mainTable.getRowIdentColumns().iterator();
if (pk_it.hasNext()) {
pkc = pk_it.next();
sourceRecordPK = sourceRecord.getValue(pkc.getDataProviderID());
if (sourceRecordPK == null)
sourceRecordPK = ValueFactory.createNullValue(pkc.getType());
combinedDestinationRecordPK = combinedDestinationRecord.getValue(pkc.getDataProviderID());
if (combinedDestinationRecordPK == null)
combinedDestinationRecordPK = ValueFactory.createNullValue(pkc.getType());
// multipk not supported
if (pk_it.hasNext())
return false;
}
List<SQLStatement> updates = new ArrayList<SQLStatement>();
IServer server = application.getSolution().getServer(mainTable.getServerName());
if (server != null) {
Iterator<String> it = server.getTableNames(false).iterator();
while (it.hasNext()) {
String tableName = it.next();
Table table = (Table) server.getTable(tableName);
// not supported
if (table.getRowIdentColumnsCount() > 1)
continue;
Iterator<Column> it2 = table.getColumns().iterator();
while (it2.hasNext()) {
Column c = it2.next();
if (c.getColumnInfo() != null) {
if (mainTableForeignType.equalsIgnoreCase(c.getColumnInfo().getForeignType())) {
// update table set foreigntypecolumn = combinedDestinationRecordPK where foreigntypecolumn = sourceRecordPK
QueryTable qTable = new QueryTable(table.getSQLName(), table.getDataSource(), table.getCatalog(), table.getSchema());
QueryUpdate qUpdate = new QueryUpdate(qTable);
QueryColumn qc = c.queryColumn(qTable);
qUpdate.addValue(qc, combinedDestinationRecordPK);
ISQLCondition condition = new CompareCondition(IBaseSQLCondition.EQUALS_OPERATOR, qc, sourceRecordPK);
qUpdate.setCondition(condition);
IDataSet pks = new BufferedDataSet();
// unknown number of records changed
pks.addRow(new Object[] { ValueFactory.createTableFlushValue() });
SQLStatement statement = new SQLStatement(ISQLActionTypes.UPDATE_ACTION, table.getServerName(), table.getName(), pks, transaction_id, qUpdate, fsm.getTableFilterParams(table.getServerName(), qUpdate));
updates.add(statement);
}
}
}
}
}
IDataSet pks = new BufferedDataSet();
pks.addRow(new Object[] { sourceRecordPK });
QueryTable qTable = new QueryTable(mainTable.getSQLName(), mainTable.getDataSource(), mainTable.getCatalog(), mainTable.getSchema());
QueryDelete qDelete = new QueryDelete(qTable);
ISQLCondition condition = new CompareCondition(IBaseSQLCondition.EQUALS_OPERATOR, pkc.queryColumn(qTable), sourceRecordPK);
qDelete.setCondition(condition);
SQLStatement statement = new SQLStatement(ISQLActionTypes.DELETE_ACTION, mainTable.getServerName(), mainTable.getName(), pks, transaction_id, qDelete, fsm.getTableFilterParams(mainTable.getServerName(), qDelete));
// check that the row is really deleted
statement.setExpectedUpdateCount(1);
updates.add(statement);
IFoundSetInternal sfs = sourceRecord.getParentFoundSet();
if (combinedDestinationRecord.startEditing()) {
if (columnNames != null) {
for (String element : columnNames) {
if (element == null)
continue;
if (sfs.getColumnIndex(element) >= 0) {
combinedDestinationRecord.setValue(element, sourceRecord.getValue(element));
}
}
}
fsm.getEditRecordList().stopEditing(true, combinedDestinationRecord);
} else {
return false;
}
Object[] results = fsm.getDataServer().performUpdates(fsm.getApplication().getClientID(), updates.toArray(new ISQLStatement[updates.size()]));
for (int i = 0; results != null && i < results.length; i++) {
if (results[i] instanceof ServoyException) {
throw (ServoyException) results[i];
}
}
// sfs.deleteRecord(sfs.getRecordIndex(sourceRecord), true); not needed, will be flushed from memory in finally
return true;
} catch (Exception ex) {
// $NON-NLS-1$
application.handleException(// $NON-NLS-1$
application.getI18NMessage("servoy.foundsetupdater.updateFailed"), new ApplicationException(ServoyException.SAVE_FAILED, ex));
} finally {
fsm.flushCachedDatabaseData(null);
}
}
return false;
}
Aggregations