mirror of
https://github.com/dbeaver/cloudbeaver.git
synced 2026-09-24 16:04:36 +08:00
CB-153 Batch update implementation
This commit is contained in:
+3
-2
@@ -68,8 +68,9 @@ public interface DBWServiceSQL extends DBWService {
|
||||
WebSQLExecuteInfo updateResultsDataBatch(
|
||||
@NotNull WebSQLContextInfo contextInfo,
|
||||
@NotNull String resultsId,
|
||||
@NotNull List<Object> updateRow,
|
||||
@NotNull Map<String, Object> updateValues) throws DBWebException;
|
||||
@Nullable List<WebSQLResultsRow> updatedRows,
|
||||
@Nullable List<WebSQLResultsRow> deletedRows,
|
||||
@Nullable List<WebSQLResultsRow> addedRows) throws DBWebException;
|
||||
|
||||
@WebAction
|
||||
WebAsyncTaskInfo asyncExecuteQuery(@NotNull WebSQLContextInfo contextInfo, @NotNull String sql, @Nullable WebSQLDataFilter filter) throws DBException;
|
||||
|
||||
+100
@@ -294,6 +294,106 @@ public class WebSQLProcessor {
|
||||
return result;
|
||||
}
|
||||
|
||||
@WebAction
|
||||
public WebSQLExecuteInfo updateResultsDataBatch(
|
||||
@NotNull WebSQLContextInfo contextInfo,
|
||||
@NotNull String resultsId,
|
||||
@Nullable List<WebSQLResultsRow> updatedRows,
|
||||
@Nullable List<WebSQLResultsRow> deletedRows,
|
||||
@Nullable List<WebSQLResultsRow> addedRows) throws DBWebException
|
||||
{
|
||||
WebSQLResultsInfo resultsInfo = contextInfo.getResults(resultsId);
|
||||
|
||||
DBDRowIdentifier rowIdentifier = resultsInfo.getDefaultRowIdentifier();
|
||||
if (rowIdentifier == null) {
|
||||
throw new DBWebException("Can't detect row identifier for results '" + resultsId + "'");
|
||||
}
|
||||
DBSEntity dataContainer = rowIdentifier.getEntity();
|
||||
if (!(dataContainer instanceof DBSDataManipulator)) {
|
||||
throw new DBWebException("Data container '" + dataContainer.getName() + "' is not editable");
|
||||
}
|
||||
DBSDataManipulator dataManipulator = (DBSDataManipulator) dataContainer;
|
||||
|
||||
DBRProgressMonitor monitor = webSession.getProgressMonitor();
|
||||
WebSQLExecuteInfo result = new WebSQLExecuteInfo();
|
||||
List<WebSQLQueryResults> queryResults = new ArrayList<>();
|
||||
|
||||
try {
|
||||
DBExecUtils.tryExecuteRecover(monitor, connection.getDataSource(), param -> {
|
||||
try {
|
||||
DBCExecutionContext executionContext = getExecutionContext(dataManipulator);
|
||||
try (DBCSession session = executionContext.openSession(monitor, DBCExecutionPurpose.USER, "Update rows in container")) {
|
||||
WebExecutionSource executionSource = new WebExecutionSource(dataManipulator, executionContext, this);
|
||||
|
||||
DBDAttributeBinding[] allAttributes = resultsInfo.getAttributes();
|
||||
DBDAttributeBinding[] keyAttributes = rowIdentifier.getAttributes().toArray(new DBDAttributeBinding[0]);
|
||||
|
||||
if (!CommonUtils.isEmpty(updatedRows)) {
|
||||
for (WebSQLResultsRow row : updatedRows) {
|
||||
Map<String, Object> updateValues = row.getUpdateValues();
|
||||
if (CommonUtils.isEmpty(row.getData()) || CommonUtils.isEmpty(updateValues)) {
|
||||
continue;
|
||||
}
|
||||
DBDAttributeBinding[] updateAttributes = new DBDAttributeBinding[updateValues.size()];
|
||||
// Final row is what we return back
|
||||
Object[] finalRow = row.getData().toArray();
|
||||
|
||||
int index = 0;
|
||||
for (String indexStr : updateValues.keySet()) {
|
||||
int attrIndex = CommonUtils.toInt(indexStr, -1);
|
||||
updateAttributes[index++] = allAttributes[attrIndex];
|
||||
}
|
||||
|
||||
Object[] rowValues = new Object[updateAttributes.length + keyAttributes.length];
|
||||
for (int i = 0; i < updateAttributes.length; i++) {
|
||||
DBDAttributeBinding updateAttribute = updateAttributes[i];
|
||||
Object cellRawValue = updateValues.get(String.valueOf(updateAttribute.getOrdinalPosition()));
|
||||
Object realCellValue = updateAttribute.getValueHandler().getValueFromObject(session, updateAttribute, cellRawValue, false, true);
|
||||
rowValues[i] = realCellValue;
|
||||
finalRow[updateAttribute.getOrdinalPosition()] = WebSQLUtils.makeWebCellValue(monitor, null, realCellValue);
|
||||
}
|
||||
for (int i = 0; i < keyAttributes.length; i++) {
|
||||
DBDAttributeBinding keyAttribute = keyAttributes[i];
|
||||
Object cellValueRaw = finalRow[keyAttribute.getOrdinalPosition()];
|
||||
rowValues[updateAttributes.length + i] = keyAttribute.getValueHandler().getValueFromObject(session, keyAttribute, cellValueRaw, false, true);
|
||||
}
|
||||
|
||||
DBSDataManipulator.ExecuteBatch updateBatch = dataManipulator.updateData(session, updateAttributes, keyAttributes, null, executionSource);
|
||||
updateBatch.add(rowValues);
|
||||
DBCStatistics statistics = updateBatch.execute(session);
|
||||
|
||||
WebSQLQueryResultSet updatedResultSet = new WebSQLQueryResultSet();
|
||||
updatedResultSet.setResultsInfo(resultsInfo);
|
||||
updatedResultSet.setColumns(resultsInfo.getAttributes());
|
||||
updatedResultSet.setRows(new Object[][]{finalRow});
|
||||
|
||||
WebSQLQueryResults updateResults = new WebSQLQueryResults();
|
||||
updateResults.setUpdateRowCount((int) statistics.getRowsUpdated());
|
||||
updateResults.setResultSet(updatedResultSet);
|
||||
queryResults.add(updateResults);
|
||||
result.setDuration(result.getDuration() + statistics.getExecuteTime());
|
||||
}
|
||||
}
|
||||
|
||||
if (!CommonUtils.isEmpty(updatedRows)) {
|
||||
throw new DBCException("New row add is not supported");
|
||||
}
|
||||
|
||||
if (!CommonUtils.isEmpty(deletedRows)) {
|
||||
throw new DBCException("Row delete is not supported");
|
||||
}
|
||||
}
|
||||
} catch (Exception e) {
|
||||
throw new InvocationTargetException(e);
|
||||
}
|
||||
});
|
||||
} catch (DBException e) {
|
||||
throw new DBWebException("Error updating data", e);
|
||||
}
|
||||
result.setResults(queryResults.toArray(new WebSQLQueryResults[0]));
|
||||
return result;
|
||||
}
|
||||
|
||||
@NotNull
|
||||
public <T> T getDataContainerByNodePath(DBRProgressMonitor monitor, @NotNull String containerPath, Class<T> type) throws DBException {
|
||||
DBNNode node = webSession.getNavigatorModel().getNodeByPath(monitor, containerPath);
|
||||
|
||||
+47
@@ -0,0 +1,47 @@
|
||||
/*
|
||||
* DBeaver - Universal Database Manager
|
||||
* Copyright (C) 2010-2020 DBeaver Corp and others
|
||||
*
|
||||
* Licensed under the Apache License, Version 2.0 (the "License");
|
||||
* you may not use this file except in compliance with the License.
|
||||
* You may obtain a copy of the License at
|
||||
*
|
||||
* http://www.apache.org/licenses/LICENSE-2.0
|
||||
*
|
||||
* Unless required by applicable law or agreed to in writing, software
|
||||
* distributed under the License is distributed on an "AS IS" BASIS,
|
||||
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
|
||||
* See the License for the specific language governing permissions and
|
||||
* limitations under the License.
|
||||
*/
|
||||
package io.cloudbeaver.service.sql;
|
||||
|
||||
import org.jkiss.dbeaver.model.data.json.JSONUtils;
|
||||
|
||||
import java.util.List;
|
||||
import java.util.Map;
|
||||
|
||||
/**
|
||||
* Web query results row.
|
||||
*/
|
||||
public class WebSQLResultsRow {
|
||||
|
||||
private List<?> data;
|
||||
private Map<String, Object> updateValues;
|
||||
|
||||
public WebSQLResultsRow() {
|
||||
}
|
||||
|
||||
public WebSQLResultsRow(Map<String, Object> map) {
|
||||
data = JSONUtils.getObjectList(map, "data");
|
||||
updateValues = JSONUtils.getObject(map, "updateValues");
|
||||
}
|
||||
|
||||
public List<?> getData() {
|
||||
return data;
|
||||
}
|
||||
|
||||
public Map<String, Object> getUpdateValues() {
|
||||
return updateValues;
|
||||
}
|
||||
}
|
||||
+20
@@ -24,9 +24,12 @@ import io.cloudbeaver.service.DBWBindingContext;
|
||||
import io.cloudbeaver.service.WebServiceBindingBase;
|
||||
import io.cloudbeaver.service.sql.impl.WebServiceSQL;
|
||||
import org.jkiss.dbeaver.DBException;
|
||||
import org.jkiss.utils.CommonUtils;
|
||||
|
||||
import java.util.HashMap;
|
||||
import java.util.List;
|
||||
import java.util.Map;
|
||||
import java.util.stream.Collectors;
|
||||
|
||||
/**
|
||||
* Web service implementation
|
||||
@@ -90,6 +93,14 @@ public class WebServiceBindingSQL extends WebServiceBindingBase<DBWServiceSQL> {
|
||||
env.getArgument("updateRow"),
|
||||
env.getArgument("updateValues")
|
||||
))
|
||||
.dataFetcher("updateResultsDataBatch", env ->
|
||||
getService(env).updateResultsDataBatch(
|
||||
getSQLContext(env),
|
||||
env.getArgument("resultsId"),
|
||||
getResultsRow(env, "updatedRows"),
|
||||
getResultsRow(env, "deletedRows"),
|
||||
getResultsRow(env, "addedRows")
|
||||
))
|
||||
.dataFetcher("asyncSqlExecuteQuery", env ->
|
||||
getService(env).asyncExecuteQuery(
|
||||
getSQLContext(env),
|
||||
@@ -154,4 +165,13 @@ public class WebServiceBindingSQL extends WebServiceBindingBase<DBWServiceSQL> {
|
||||
Map<String, Object> filterProps = env.getArgument("filter");
|
||||
return filterProps == null ? null : new WebSQLDataFilter(filterProps);
|
||||
}
|
||||
|
||||
private static List<WebSQLResultsRow> getResultsRow(DataFetchingEnvironment env, String param) {
|
||||
List<Map<String, Object>> mapList = env.getArgument("param");
|
||||
if (CommonUtils.isEmpty(mapList)) {
|
||||
return null;
|
||||
}
|
||||
return mapList.stream().map(WebSQLResultsRow::new).collect(Collectors.toList());
|
||||
}
|
||||
|
||||
}
|
||||
|
||||
+2
-2
@@ -144,8 +144,8 @@ public class WebServiceSQL implements DBWServiceSQL {
|
||||
}
|
||||
|
||||
@Override
|
||||
public WebSQLExecuteInfo updateResultsDataBatch(@NotNull WebSQLContextInfo contextInfo, @NotNull String resultsId, @NotNull List<Object> updateRow, @NotNull Map<String, Object> updateValues) throws DBWebException {
|
||||
throw new DBWebException("Not supported");
|
||||
public WebSQLExecuteInfo updateResultsDataBatch(@NotNull WebSQLContextInfo contextInfo, @NotNull String resultsId, @Nullable List<WebSQLResultsRow> updatedRows, @Nullable List<WebSQLResultsRow> deletedRows, @Nullable List<WebSQLResultsRow> addedRows) throws DBWebException {
|
||||
return contextInfo.getProcessor().updateResultsDataBatch(contextInfo, resultsId, updatedRows, deletedRows, addedRows);
|
||||
}
|
||||
|
||||
@NotNull
|
||||
|
||||
Reference in New Issue
Block a user