use of com.servoy.j2db.util.ServoyException 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.util.ServoyException in project servoy-client by Servoy.
the class FoundSet method performQuery.
protected IDataSet performQuery(String transaction_id, QuerySelect query, ColumnType[] resultTypes, int startRow, int rowsToRetrieve, int type) throws RemoteException, ServoyException {
if (!hasAccess(IRepository.READ)) {
fireDifference(getSize(), 0, null);
throw new ApplicationException(ServoyException.NO_ACCESS, new Object[] { getSQLSheet().getTable().getName() });
}
QuerySelect theQuery = query;
IDataSet dataSet = SQLGenerator.getEmptyDataSetForDummyQuery(theQuery);
if (dataSet != null) {
// just return empty data set, prevent 'where 1=2' queries
if (Debug.tracing()) {
Debug.trace("Skipping reload query on cleared foundset for data source " + getDataSource());
}
return dataSet;
}
try {
boolean distinctInMemory = !theQuery.isUnique();
if (!theQuery.isDistinct() && !distinctInMemory && hasTablefilterWithJoins(theQuery)) {
// table filters adds joins that cause duplicate results
if (theQuery.getColumns().size() == 1 && isDistinctAllowed(theQuery.getColumns(), theQuery.getSorts())) {
// we can set distinct
QuerySelect copy = (QuerySelect) theQuery.shallowClone();
copy.setDistinct(true);
theQuery = copy;
} else {
// cannot set distinct, make sure we filter out duplicate records
distinctInMemory = true;
}
}
return fsm.getDataServer().performQuery(fsm.getApplication().getClientID(), sheet.getServerName(), transaction_id, theQuery, resultTypes, fsm.getTableFilterParams(sheet.getServerName(), theQuery), distinctInMemory, startRow, rowsToRetrieve, type);
} catch (ServoyException e) {
e.setContext(this.toString());
throw e;
} catch (CloneNotSupportedException e) {
// should not happen
throw new RuntimeException(e);
}
}
use of com.servoy.j2db.util.ServoyException in project servoy-client by Servoy.
the class FoundSetManager method executeFoundsetTriggerInternal.
private Object executeFoundsetTriggerInternal(ITable table, Object[] args, TypedProperty<Integer> property, TriggerExecutionMode executionMode, boolean throwException, Scriptable foundsetScope) throws ServoyException {
IExecutingEnviroment scriptEngine = getApplication().getScriptEngine();
List<TriggerFunction> functions = getTriggerFunctions(table, property, foundsetScope);
if (executionMode == ReturnFirst && functions.size() > 1) {
Debug.warn("Multiple event handlers found for event " + property.getPropertyName() + ", only executing one");
}
for (TriggerFunction function : functions) {
try {
Object returnValue = scriptEngine.executeFunction(function.getFunction(), function.getScope(), function.getScope(), arrayMerge(args, parseJSExpressions(function.getTableNode().getFlattenedMethodArguments(property.getPropertyName()))), false, throwException);
if (executionMode == ReturnFirst || (executionMode == BreakOnFalse && Boolean.FALSE.equals(returnValue))) {
// return first value or break on false return, do not execute remaining triggers.
return returnValue;
}
} catch (JavaScriptException e) {
// update or insert method threw exception.
throw new DataException(ServoyException.RECORD_VALIDATION_FAILED, e.getValue(), e).setContext(this.toString());
} catch (EcmaError e) {
throw new ApplicationException(ServoyException.SAVE_FAILED, e).setContext(this.toString());
} catch (Exception e) {
Debug.error(e);
throw new ServoyException(ServoyException.SAVE_FAILED, new Object[] { e.getMessage() }).setContext(this.toString());
}
}
return Boolean.TRUE;
}
use of com.servoy.j2db.util.ServoyException in project servoy-client by Servoy.
the class RowManager method removeRowReferences.
/**
* Remove references in other RowManagers to this row.
* @param pkHashKey
* @param calc, null for all
*/
public void removeRowReferences(String pkHashKey, String calc) {
SoftReferenceWithData<Row, Pair<Map<String, List<CalculationDependency>>, CalculationDependencyData>> sr = pkRowMap.get(pkHashKey);
if (sr != null) {
CalculationDependencyData rowRefs = null;
synchronized (sr) {
// check the calculation dependencies registered for the calc
Pair<Map<String, List<CalculationDependency>>, CalculationDependencyData> data = sr.getData();
if (data != null) {
CalculationDependencyData calcRowrefs = data.getRight();
if (calcRowrefs != null) {
// remove both row refs and relation dependencies
if (calc == null) {
rowRefs = calcRowrefs;
data.setRight(null);
} else {
List<RowReference> refs = calcRowrefs.removeReferences(calc);
if (refs != null) {
rowRefs = new CalculationDependencyData();
rowRefs.putRowReferences(calc, refs);
}
}
}
}
}
if (rowRefs != null) {
String dataSource = fsm.getDataSource(sheet.getTable());
for (Entry<String, List<RowReference>> entry : rowRefs.getRowReferencesEntrySet()) {
for (RowReference reference : entry.getValue()) {
try {
getFoundsetManager().getRowManager(reference.dataSource).removeCalculationDependency(reference.pkHashKey, reference.dataproviderId, dataSource, pkHashKey, entry.getKey());
} catch (ServoyException e) {
Debug.log(e);
}
}
}
}
}
}
use of com.servoy.j2db.util.ServoyException 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