Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

CB-4285 read full value from text cell #2288

Merged
merged 25 commits into from
Jan 17, 2024
Merged
Show file tree
Hide file tree
Changes from 11 commits
Commits
Show all changes
25 commits
Select commit Hold shift + click to select a range
66f8f99
CB-4494 api for reading full value from text cell
yagudin10 Jan 10, 2024
b17c928
CB-4494 apply function fix
yagudin10 Jan 11, 2024
0bb3795
CB-4285 graphql getFileFullText for files
Jan 11, 2024
8b29d54
Merge branch 'devel' into CB-4285-read-text-value
Jan 11, 2024
6ede59b
CB-4285 textValuePresentation refactor
Jan 12, 2024
9afb68d
CB-4285 textValuePresentation refactor - removed unneeded fields
Jan 12, 2024
e560db5
CB-4285 textValuePresentation canSave in data ref
Jan 12, 2024
e677348
CB-4285 paste full text button
Jan 12, 2024
ea2985f
CB-4285 observable map for full text in textValuePresentation
Jan 12, 2024
dc97ea4
CB-4285 reset cases comment removed (all works cool)
Jan 12, 2024
171f5a4
СB-4285 buttons in tools container is now nearby each other
Jan 12, 2024
f298593
Merge branch 'devel' into CB-4285-read-text-value
Jan 12, 2024
f9266b0
Merge remote-tracking branch 'origin/devel' into CB-4285-read-text-value
yagudin10 Jan 12, 2024
47031b4
CB-4285 use content action for caching full texts
Jan 12, 2024
5127cad
CB-3842 use only one row in getting full value
yagudin10 Jan 12, 2024
3a2ba83
Merge remote-tracking branch 'origin/CB-4285-read-text-value' into CB…
yagudin10 Jan 12, 2024
7caa067
CB-3842 use not null at read lob value
yagudin10 Jan 12, 2024
9aae661
Merge branch 'devel' into CB-4285-read-text-value
Jan 13, 2024
76e3d94
CB-4285 schema changes for sqlReadString and sqlReadLobValue
Jan 14, 2024
6991995
CB-4285 TextValuePresentation refactor
Jan 14, 2024
6a78d72
CB-4285 useTextValue refactor
Jan 14, 2024
36bb388
CB-4285 PR comments applied
Jan 15, 2024
6116402
Merge branch 'devel' into CB-4285-read-text-value
EvgeniaBzzz Jan 17, 2024
17d9813
CB-4285 view full text button for ValuePanel + remove truncated warni…
Jan 17, 2024
e0d85a7
Merge branch 'devel' into CB-4285-read-text-value
EvgeniaBzzz Jan 17, 2024
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
12 changes: 11 additions & 1 deletion server/bundles/io.cloudbeaver.server/schema/service.sql.graphqls
Original file line number Diff line number Diff line change
Expand Up @@ -331,7 +331,7 @@ extend type Mutation {
addedRows: [ SQLResultRow! ],
): String!

#Return BLOB name
# Returns BLOB name
readLobValue(
projectId: ID,
connectionId: ID!,
Expand All @@ -341,6 +341,16 @@ extend type Mutation {
row: [ SQLResultRow! ]!
): String!

# Returns full string value
yagudin10 marked this conversation as resolved.
Show resolved Hide resolved
sqlReadStringValue(
projectId: ID,
connectionId: ID!,
contextId: ID!,
resultsId: ID!,
columnIndex: Int!,
row: [ SQLResultRow! ]!
): String!
yagudin10 marked this conversation as resolved.
Show resolved Hide resolved

# Returns SQLExecuteInfo
asyncSqlExecuteResults(taskId: ID!): SQLExecuteInfo !

Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -124,6 +124,14 @@ String readLobValue(
@NotNull Integer lobColumnIndex,
@Nullable List<WebSQLResultsRow> row) throws DBWebException;

@NotNull
@WebAction
String getCellValue(
@NotNull WebSQLContextInfo contextInfo,
@NotNull String resultsId,
@NotNull Integer lobColumnIndex,
@Nullable List<WebSQLResultsRow> row) throws DBWebException;

@WebAction
String updateResultsDataBatchScript(
@NotNull WebSQLContextInfo contextInfo,
Expand Down
Original file line number Diff line number Diff line change
@@ -0,0 +1,85 @@
/*
* DBeaver - Universal Database Manager
* Copyright (C) 2010-2024 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.code.NotNull;
import org.jkiss.dbeaver.model.data.DBDAttributeBindingMeta;
import org.jkiss.dbeaver.model.data.DBDContent;
import org.jkiss.dbeaver.model.data.DBDDataReceiver;
import org.jkiss.dbeaver.model.data.DBDValue;
import org.jkiss.dbeaver.model.exec.*;
import org.jkiss.dbeaver.model.runtime.DBRProgressMonitor;
import org.jkiss.dbeaver.model.struct.DBSDataContainer;
import org.jkiss.dbeaver.utils.ContentUtils;

import java.nio.charset.StandardCharsets;
import java.util.List;

public class WebSQLCellValueReceiver implements DBDDataReceiver {
protected final DBSDataContainer dataContainer;
protected int rowIndex;
protected DBDAttributeBindingMeta binding;
protected Object value;

public WebSQLCellValueReceiver(DBSDataContainer dataContainer, int rowIndex) {
this.dataContainer = dataContainer;
this.rowIndex = rowIndex;
}

@Override
public void fetchStart(DBCSession session, DBCResultSet resultSet, long offset, long maxRows) throws DBCException {
DBCResultSetMetaData meta = resultSet.getMeta();
List<DBCAttributeMetaData> attributes = meta.getAttributes();
DBCAttributeMetaData attrMeta = attributes.get(rowIndex);
binding = new DBDAttributeBindingMeta(dataContainer, resultSet.getSession(), attrMeta);
}

@Override
public void fetchRow(DBCSession session, DBCResultSet resultSet) throws DBCException {
value = binding.getValueHandler().fetchValueObject(
resultSet.getSession(),
resultSet,
binding.getMetaAttribute(),
rowIndex);
}

@Override
public void fetchEnd(DBCSession session, DBCResultSet resultSet) throws DBCException {

}

@Override
public void close() {

}

@NotNull
public byte[] getBinaryValue(DBRProgressMonitor monitor) throws DBCException {
byte[] binaryValue;
if (value instanceof DBDContent dbdContent) {
binaryValue = ContentUtils.getContentBinaryValue(monitor, dbdContent);
} else if (value instanceof DBDValue dbdValue) {
binaryValue = dbdValue.getRawValue().toString().getBytes();
} else {
binaryValue = value.toString().getBytes(StandardCharsets.UTF_8);
}
if (binaryValue == null) {
throw new DBCException("Lob value is null");
}
return binaryValue;
}
}
Original file line number Diff line number Diff line change
Expand Up @@ -20,39 +20,29 @@
import io.cloudbeaver.server.CBConstants;
import io.cloudbeaver.server.CBPlatform;
import org.jkiss.dbeaver.Log;
import org.jkiss.dbeaver.model.data.*;
import org.jkiss.dbeaver.model.exec.*;
import org.jkiss.dbeaver.model.runtime.DBRProgressMonitor;
import org.jkiss.dbeaver.model.runtime.VoidProgressMonitor;
import org.jkiss.dbeaver.model.sql.DBQuotaException;
import org.jkiss.dbeaver.model.struct.DBSDataContainer;
import org.jkiss.dbeaver.utils.ContentUtils;
import org.jkiss.utils.CommonUtils;

import java.io.IOException;
import java.nio.charset.StandardCharsets;
import java.nio.file.Files;
import java.nio.file.Path;
import java.sql.Timestamp;
import java.text.SimpleDateFormat;
import java.util.List;


public class WebSQLDataLOBReceiver implements DBDDataReceiver {
public class WebSQLDataLOBReceiver extends WebSQLCellValueReceiver {
private static final Log log = Log.getLog(WebSQLDataLOBReceiver.class);
public static final Path DATA_EXPORT_FOLDER = CBPlatform.getInstance().getTempFolder(new VoidProgressMonitor(), "sql-lob-files");

private final String tableName;
private final DBSDataContainer dataContainer;

private DBDAttributeBinding binding;
private Object lobValue;
private int rowIndex;

WebSQLDataLOBReceiver(String tableName, DBSDataContainer dataContainer, int rowIndex) {
super(dataContainer, rowIndex);
this.tableName = tableName;
this.dataContainer = dataContainer;
this.rowIndex = rowIndex;
if (!Files.exists(DATA_EXPORT_FOLDER)){
if (!Files.exists(DATA_EXPORT_FOLDER)) {
try {
Files.createDirectories(DATA_EXPORT_FOLDER);
} catch (IOException e) {
Expand All @@ -62,64 +52,28 @@ public class WebSQLDataLOBReceiver implements DBDDataReceiver {

}

public String createLobFile(DBCSession session) throws DBCException, IOException {
public String createLobFile(DBRProgressMonitor monitor) throws DBCException, IOException {
String exportFileName = CommonUtils.truncateString(tableName, 32);
StringBuilder fileName = new StringBuilder(exportFileName);
fileName.append("_")
.append(binding.getName())
.append("_");
.append(binding.getName())
.append("_");
Timestamp ts = new Timestamp(System.currentTimeMillis());
String s = new SimpleDateFormat("yyyy-MM-dd_HH-mm-ss").format(ts);
fileName.append(s);
exportFileName = CommonUtils.escapeFileName(fileName.toString());
byte[] binaryValue;
byte[] binaryValue = getBinaryValue(monitor);
Number fileSizeLimit = CBApplication.getInstance().getAppConfiguration().getResourceQuota(CBConstants.QUOTA_PROP_FILE_LIMIT);
if (lobValue instanceof DBDContent) {
binaryValue = ContentUtils.getContentBinaryValue(session.getProgressMonitor(), (DBDContent) lobValue);
} else if (lobValue instanceof DBDValue) {
binaryValue = ((DBDValue) lobValue).getRawValue().toString().getBytes();
} else {
binaryValue = lobValue.toString().getBytes(StandardCharsets.UTF_8);
}
if (binaryValue == null) {
throw new DBCException("Lob value is null");
}
if (binaryValue.length > fileSizeLimit.longValue()) {
throw new DBQuotaException(
"Data export quota exceeded \n Please increase the resourceQuotas parameter in configuration",
"Data export quota exceeded \n Please increase the resourceQuotas parameter in configuration",
CBConstants.QUOTA_PROP_FILE_LIMIT, fileSizeLimit.longValue(), binaryValue.length
);
}
Path file = DATA_EXPORT_FOLDER.resolve(exportFileName);
Path file = WebSQLDataLOBReceiver.DATA_EXPORT_FOLDER.resolve(exportFileName);
Files.write(file, binaryValue);
return exportFileName;
}



@Override
public void fetchStart(DBCSession session, DBCResultSet resultSet, long offset, long maxRows) throws DBCException {
DBCResultSetMetaData meta = resultSet.getMeta();
List<DBCAttributeMetaData> attributes = meta.getAttributes();
DBCAttributeMetaData attrMeta = attributes.get(rowIndex);
binding = new DBDAttributeBindingMeta(dataContainer, resultSet.getSession(), attrMeta);
}
@Override
public void fetchRow(DBCSession session, DBCResultSet resultSet) throws DBCException {
lobValue = binding.getValueHandler().fetchValueObject(
resultSet.getSession(),
resultSet,
binding.getMetaAttribute(),
rowIndex);
}

@Override
public void fetchEnd(DBCSession session, DBCResultSet resultSet) throws DBCException {

}

@Override
public void close() {

}
}
Original file line number Diff line number Diff line change
Expand Up @@ -54,6 +54,7 @@

import java.io.IOException;
import java.lang.reflect.InvocationTargetException;
import java.nio.charset.StandardCharsets;
import java.nio.file.Files;
import java.nio.file.Path;
import java.util.*;
Expand Down Expand Up @@ -797,14 +798,27 @@ public String readLobValue(

DBDRowIdentifier rowIdentifier = resultsInfo.getDefaultRowIdentifier();
checkRowIdentifier(resultsInfo, rowIdentifier);
String tableName = rowIdentifier.getEntity().getName();
WebSQLDataLOBReceiver dataReceiver = new WebSQLDataLOBReceiver(tableName, resultsInfo.getDataContainer(), lobColumnIndex);
readCellDataValue(monitor, resultsInfo, row, dataReceiver);
try {
return dataReceiver.createLobFile(monitor);
} catch (Exception e) {
throw new DBWebException("Error creating temporary lob file ", e);
}
}

private void readCellDataValue(
@NotNull DBRProgressMonitor monitor,
@NotNull WebSQLResultsInfo resultsInfo,
@Nullable WebSQLResultsRow row,
@NotNull WebSQLCellValueReceiver dataReceiver) throws DBException {
DBSDataContainer dataContainer = resultsInfo.getDataContainer();
DBCExecutionContext executionContext = getExecutionContext(dataContainer);
String tableName = rowIdentifier.getEntity().getName();
WebSQLDataLOBReceiver dataReceiver = new WebSQLDataLOBReceiver(tableName, dataContainer, lobColumnIndex);
try (DBCSession session = executionContext.openSession(monitor, DBCExecutionPurpose.USER, "Generate data update batches")) {
WebExecutionSource executionSource = new WebExecutionSource(dataContainer, executionContext, this);
DBDDataFilter dataFilter = new DBDDataFilter();
DBDAttributeBinding[] keyAttributes = rowIdentifier.getAttributes().toArray(new DBDAttributeBinding[0]);
DBDAttributeBinding[] keyAttributes = resultsInfo.getDefaultRowIdentifier().getAttributes().toArray(new DBDAttributeBinding[0]);
Object[] rowValues = new Object[keyAttributes.length];
List<DBDAttributeConstraint> constraints = new ArrayList<>();
for (int i = 0; i < keyAttributes.length; i++) {
Expand Down Expand Up @@ -833,14 +847,25 @@ public String readLobValue(
DBCStatistics statistics = dataContainer.readData(
executionSource, session, dataReceiver, dataFilter,
0, 1, DBSDataContainer.FLAG_NONE, 1);
try {
return dataReceiver.createLobFile(session);
} catch (Exception e) {
throw new DBWebException("Error creating temporary lob file ", e);
}
}
}

@NotNull
public String readStringValue(
@NotNull DBRProgressMonitor monitor,
@NotNull WebSQLContextInfo contextInfo,
@NotNull String resultsId,
@NotNull Integer columnIndex,
@Nullable WebSQLResultsRow row
) throws DBException {
WebSQLResultsInfo resultsInfo = contextInfo.getResults(resultsId);
DBDRowIdentifier rowIdentifier = resultsInfo.getDefaultRowIdentifier();
checkRowIdentifier(resultsInfo, rowIdentifier);
WebSQLCellValueReceiver dataReceiver = new WebSQLCellValueReceiver(resultsInfo.getDataContainer(), columnIndex);
readCellDataValue(monitor, resultsInfo, row, dataReceiver);
return new String(dataReceiver.getBinaryValue(monitor), StandardCharsets.UTF_8);
}

////////////////////////////////////////////////
// Misc

Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -137,6 +137,12 @@ public void bindWiring(DBWBindingContext model) throws DBWebException {
env.getArgument("resultsId"),
env.getArgument("lobColumnIndex"),
getResultsRow(env, "row")))
.dataFetcher("sqlReadStringValue", env ->
getService(env).getCellValue(
getSQLContext(env),
env.getArgument("resultsId"),
env.getArgument("columnIndex"),
getResultsRow(env, "row")))
.dataFetcher("updateResultsDataBatch", env ->
getService(env).updateResultsDataBatch(
getSQLContext(env),
Expand Down
Loading
Loading