[DBE-9310] Force full load big fields

Merge-request: IJ-MR-152308
Merged-by: Anvar Ramazanov <anvar.ramazanov@jetbrains.com>

GitOrigin-RevId: 931a5b0ae734ba101e69b7318fcf39680078ee62
This commit is contained in:
Anvar Ramazanov
2025-02-07 11:47:34 +00:00
committed by intellij-monorepo-bot
parent cda6881f89
commit ade82c4c52
15 changed files with 107 additions and 10 deletions
@@ -11,9 +11,13 @@ import javax.swing.*;
*/
@org.jetbrains.annotations.ApiStatus.Internal
public final class GridCoreImplIcons {
private static @NotNull Icon load(@NotNull String path, int cacheKey, int flags) {
return IconManager.getInstance().loadRasterizedIcon(path, GridCoreImplIcons.class.getClassLoader(), cacheKey, flags);
}
private static @NotNull Icon load(@NotNull String expUIPath, @NotNull String path, int cacheKey, int flags) {
return IconManager.getInstance().loadRasterizedIcon(path, expUIPath, GridCoreImplIcons.class.getClassLoader(), cacheKey, flags);
}
/** 16x16 */ public static final @NotNull Icon CellDownload = load("icons/cellDownload.svg", 18297100, 2);
/** 16x16 */ public static final @NotNull Icon ColumnFilter = load("icons/expui/columnFilter.svg", "icons/columnFilter.svg", -1426207601, 0);
/** 16x16 */ public static final @NotNull Icon FilterHistory = load("icons/expui/filterHistory.svg", "icons/filterHistory.svg", 686246081, 0);
/** 16x16 */ public static final @NotNull Icon SingleRecordView = load("icons/expui/singleRecordView.svg", "icons/singleRecordView.svg", 502511093, 2);
@@ -0,0 +1,4 @@
<svg width="16" height="16" viewBox="0 0 16 16" fill="none" xmlns="http://www.w3.org/2000/svg">
<path fill-rule="evenodd" clip-rule="evenodd" d="M12.8536 15.8536C12.6583 16.0488 12.3417 16.0488 12.1464 15.8536L9.14645 12.8536C8.95118 12.6583 8.95118 12.3417 9.14645 12.1464C9.34171 11.9512 9.65829 11.9512 9.85355 12.1464L12 14.2929L12 8.5C12 8.22386 12.2239 8 12.5 8C12.7761 8 13 8.22386 13 8.5L13 14.2929L15.1464 12.1464C15.3417 11.9512 15.6583 11.9512 15.8536 12.1464C16.0488 12.3417 16.0488 12.6583 15.8536 12.8536L12.8536 15.8536Z" fill="#3574F0"/>
<path d="M4.5 2C4.77614 2 5 2.22386 5 2.5V4H11V2.5C11 2.22386 11.2239 2 11.5 2C11.7761 2 12 2.22386 12 2.5V4H13.5C13.7761 4 14 4.22386 14 4.5C14 4.77614 13.7761 5 13.5 5H12V7H11V5H5V11H8V12H5V13.5C5 13.7761 4.77614 14 4.5 14C4.22386 14 4 13.7761 4 13.5V12H2.5C2.22386 12 2 11.7761 2 11.5C2 11.2239 2.22386 11 2.5 11H4V5H2.5C2.22386 5 2 4.77614 2 4.5C2 4.22386 2.22386 4 2.5 4H4V2.5C4 2.22386 4.22386 2 4.5 2Z" fill="#6C707E"/>
</svg>

After

Width:  |  Height:  |  Size: 988 B

@@ -0,0 +1,4 @@
<svg width="16" height="16" viewBox="0 0 16 16" fill="none" xmlns="http://www.w3.org/2000/svg">
<path fill-rule="evenodd" clip-rule="evenodd" d="M12.8536 15.8536C12.6583 16.0488 12.3417 16.0488 12.1464 15.8536L9.14645 12.8536C8.95118 12.6583 8.95118 12.3417 9.14645 12.1464C9.34171 11.9512 9.65829 11.9512 9.85355 12.1464L12 14.2929L12 8.5C12 8.22386 12.2239 8 12.5 8C12.7761 8 13 8.22386 13 8.5L13 14.2929L15.1464 12.1464C15.3417 11.9512 15.6583 11.9512 15.8536 12.1464C16.0488 12.3417 16.0488 12.6583 15.8536 12.8536L12.8536 15.8536Z" fill="#548AF7"/>
<path d="M4.5 2C4.77614 2 5 2.22386 5 2.5V4H11V2.5C11 2.22386 11.2239 2 11.5 2C11.7761 2 12 2.22386 12 2.5V4H13.5C13.7761 4 14 4.22386 14 4.5C14 4.77614 13.7761 5 13.5 5H12V7H11V5H5V11H8V12H5V13.5C5 13.7761 4.77614 14 4.5 14C4.22386 14 4 13.7761 4 13.5V12H2.5C2.22386 12 2 11.7761 2 11.5C2 11.2239 2.22386 11 2.5 11H4V5H2.5C2.22386 5 2 4.77614 2 4.5C2 4.22386 2.22386 4 2.5 4H4V2.5C4 2.22386 4.22386 2 4.5 2Z" fill="#CED0D6"/>
</svg>

After

Width:  |  Height:  |  Size: 988 B

@@ -389,3 +389,9 @@ grid.load.prev.nested.table.error.loading=Navigation to {0} table is not availab
progress.text.loading.data=Loading data\u2026
progress.text.loading.script=Loading script\u2026
invalid.extractor.name=Invalid extractor name: ''{0}''
action.Console.TableResult.ReloadCell.ErrorCellLoading.text=Cannot load cell value
action.Console.TableResult.SaveLobAsAction.TableChanged.text=table has been changed
action.Console.TableResult.SaveLobAsAction.AmbiguousQueryResult.text=ambiguous query result ({0} rows received)
action.Console.TableResult.ReloadCell.Confirmation.title=Warning
action.Console.TableResult.ReloadCell.Confirmation.text=One of the loaded cells contains a large amount of data, which may affect performance. Do you want to continue?
@@ -7,7 +7,7 @@ import org.jetbrains.annotations.Nullable;
import java.util.List;
import java.util.function.BiFunction;
public class DataGridListModel extends GridListModelBase<GridRow, GridColumn> {
public class DataGridListModel extends GridListModelBase<GridRow, GridColumn> implements GridModelWithInjections<GridRow, GridColumn> {
private final BiFunction<Object, Object, Boolean> myValuesEquals;
public DataGridListModel(@NotNull BiFunction<Object, Object, Boolean> valuesEquals) {
@@ -45,4 +45,12 @@ public class DataGridListModel extends GridListModelBase<GridRow, GridColumn> {
}
return true;
}
@Override
public void injectValue(@NotNull ModelIndex<GridRow> rowIndex, @NotNull ModelIndex<GridColumn> columnIndex, @NotNull Object value) {
var row = getRow(rowIndex);
if (row != null) {
row.setValue(columnIndex.value, value);
}
}
}
@@ -0,0 +1,7 @@
package com.intellij.database.datagrid;
import org.jetbrains.annotations.NotNull;
public interface GridModelWithInjections<Row, Column> extends GridModel<Row, Column> {
void injectValue(@NotNull ModelIndex<GridRow> row, @NotNull ModelIndex<GridColumn> columns, @NotNull Object what);
}
@@ -31,6 +31,11 @@ public class DatabaseObjectFormatterConfig implements ObjectFormatterConfig {
return null;
}
@Override
public boolean isAllowedShowBigObjects() {
return false;
}
@Override
public boolean equals(Object o) {
if (this == o) return true;
@@ -62,6 +67,8 @@ public class DatabaseObjectFormatterConfig implements ObjectFormatterConfig {
private final DataGridSettings settings;
private boolean isAllowedShowBigObjects;
public DatabaseDisplayObjectFormatterConfig() {
this(null, false, null, null);
}
@@ -73,6 +80,7 @@ public class DatabaseObjectFormatterConfig implements ObjectFormatterConfig {
@Nullable DataGridSettings settings
) {
super(ObjectFormatterMode.DISPLAY);
this.isAllowedShowBigObjects = false;
this.displayType = displayType;
this.isModeDetectedAutomatically = isModeDetectedAutomatically;
this.allowedTypes = allowedTypes;
@@ -97,6 +105,15 @@ public class DatabaseObjectFormatterConfig implements ObjectFormatterConfig {
return settings;
}
public void allowShowBigObjects() {
this.isAllowedShowBigObjects = true;
}
@Override
public boolean isAllowedShowBigObjects() {
return this.isAllowedShowBigObjects;
}
@Override
public boolean equals(Object o) {
if (this == o) return true;
@@ -11,4 +11,6 @@ public interface ObjectFormatterConfig {
@Nullable
DataGridSettings getSettings();
boolean isAllowedShowBigObjects();
}
+12
View File
@@ -608,6 +608,18 @@ public class GridUtil extends GridUtilCore {
};
}
public static @NotNull Function<Integer, ObjectFormatterConfig> getConfigProvider(@NotNull DataGrid dataGrid, boolean allowLongValues) {
return num -> {
ModelIndex<GridColumn> idx = ModelIndex.forColumn(dataGrid, num);
if (!allowLongValues) {
return createFormatterConfig(dataGrid, idx);
}
var config = createFormatterConfig(dataGrid, idx);
config.allowShowBigObjects();
return config;
};
}
public static boolean canMutateColumns(@Nullable DataGrid grid) {
return grid != null && GridHelper.get(grid).canMutateColumns(grid);
}
+1
View File
@@ -1,5 +1,6 @@
package com.intellij.database.run.ui
import com.intellij.database.DataGridBundle
import com.intellij.database.datagrid.*
import com.intellij.database.extractors.DisplayType
import com.intellij.database.run.ReservedCellValue
+5 -7
View File
@@ -5,11 +5,11 @@ import com.intellij.openapi.actionSystem.ActionGroup
import com.intellij.openapi.actionSystem.ActionManager
import com.intellij.openapi.actionSystem.ActionPlaces
import com.intellij.openapi.actionSystem.ActionToolbar
import com.intellij.openapi.editor.impl.EditorHeaderComponent
import com.intellij.openapi.util.NlsContexts
import com.intellij.ui.components.JBPanelWithEmptyText
import com.intellij.ui.components.TwoSideComponent
import com.intellij.ui.components.panels.Wrapper
import com.intellij.ui.tabs.TabInfo
import com.intellij.util.ui.JBUI
import java.awt.BorderLayout
import javax.swing.JPanel
@@ -19,11 +19,9 @@ import javax.swing.JPanel
abstract class TabInfoProvider(title: @NlsContexts.TabTitle String, private val actionGroup: ActionGroup?) : Disposable {
private val panel = JPanel(BorderLayout())
protected val toolbar = createToolbar()
val tabInfo = TabInfo(JBPanelWithEmptyText()).setText(title).setComponent(panel).setSideComponent(toolbar?.let {
EditorHeaderComponent().also { header ->
header.add(toolbar.component, BorderLayout.EAST)
header.border = JBUI.Borders.empty()
}
val tabInfo = TabInfo(JBPanelWithEmptyText()).setText(title).setComponent(panel)
.setSideComponent(toolbar?.let {
TwoSideComponent(Wrapper(), toolbar.component)
})
protected var isOnTab: Boolean = false
@@ -108,7 +108,7 @@ public class GridCopyProvider implements CopyProvider {
SelectionModel<GridRow, GridColumn> selectionModel = myGrid.getSelectionModel();
if (selectionModel.getSelectedRowCount() == 1 &&
selectionModel.getSelectedColumnCount() == 1) {
return GridExtractorsUtilCore.getSingleValueExtractor(myGrid.getObjectFormatter(), GridUtil.getConfigProvider(myGrid));
return GridExtractorsUtilCore.getSingleValueExtractor(myGrid.getObjectFormatter(), GridUtil.getConfigProvider(myGrid, true));
}
DataExtractorFactory extractorFactory = DataExtractorFactories.getExtractorFactory(myGrid, GridUtil::suggestPlugin);
@@ -1,9 +1,11 @@
package com.intellij.database.run.ui.table;
import com.intellij.application.options.EditorFontsConstants;
import com.intellij.database.actions.ShowEditMaximizedAction;
import com.intellij.database.datagrid.*;
import com.intellij.database.datagrid.HierarchicalColumnsDataGridModel.HierarchicalGridColumn;
import com.intellij.database.extractors.DisplayType;
import com.intellij.database.remote.jdbc.LobInfo;
import com.intellij.database.run.actions.ColumnLocalFilterAction;
import com.intellij.database.run.ui.*;
import com.intellij.database.run.ui.grid.*;
@@ -25,6 +27,7 @@ import com.intellij.ide.ui.UISettingsListener;
import com.intellij.ide.ui.UISettingsUtils;
import com.intellij.lang.Language;
import com.intellij.openapi.actionSystem.*;
import com.intellij.openapi.actionSystem.ex.ActionUtil;
import com.intellij.openapi.application.ApplicationManager;
import com.intellij.openapi.editor.colors.EditorColorsListener;
import com.intellij.openapi.editor.colors.EditorColorsScheme;
@@ -1295,6 +1298,10 @@ public final class TableResultView extends JBTableWithResizableCells
@Override
public boolean editCellAt(int row, int column, EventObject e) {
ClientProperty.put(this, GridTableCellEditor.EDITING_STARTER_CLIENT_PROPERTY_KEY, e);
if (shouldDisplayValueEditor(row, column)) {
showValueEditor(e);
return false;
}
try {
return super.editCellAt(row, column, e);
}
@@ -1303,6 +1310,23 @@ public final class TableResultView extends JBTableWithResizableCells
}
}
private boolean shouldDisplayValueEditor(int row, int column) {
var tableModel = getModel();
var cellValue = tableModel.getValueAt(row, column);
return cellValue instanceof LobInfo.ClobInfo clob && clob.isFullyReloaded();
}
private void showValueEditor(EventObject e) {
if (e instanceof MouseEvent mouseEvent && mouseEvent.getClickCount() < 2) return;
if (e instanceof KeyEvent && !UIUtil.isReallyTypedEvent((KeyEvent)e)) return;
var action = ActionUtil.wrap("Console.TableResult.EditValueMaximized");
var dataContext = DataManager.getInstance().getDataContext(this);
AnActionEvent event = AnActionEvent.createEvent(action, dataContext, null, ActionPlaces.UNKNOWN, ActionUiKind.NONE, null);
var view = ShowEditMaximizedAction.getView(this.myResultPanel, event);
view.open(tabInfoProvider -> tabInfoProvider instanceof ValueTabInfoProvider);
}
@Override
public void createDefaultColumnsFromModel() {
GridTableModel model = getModel();
+10
View File
@@ -20,6 +20,8 @@ import java.util.Objects;
public abstract class LobInfo<T extends LobInfo<?>> implements Comparable<T>, Serializable {
public final long length;
private boolean isFullyReloaded;
private static final ThreadLocal<byte[]> BUFFER = new ThreadLocal<byte[]>() {
@Override
protected byte[] initialValue() {
@@ -35,6 +37,14 @@ public abstract class LobInfo<T extends LobInfo<?>> implements Comparable<T>, Se
return length != getLoadedDataLength();
}
public boolean isFullyReloaded() {
return isFullyReloaded;
}
public void setFullyReloaded(boolean fullyReloaded) {
this.isFullyReloaded = fullyReloaded;
}
public abstract long getLoadedDataLength();
@Override
@@ -1,4 +1,4 @@
// Copyright 2000-2023 JetBrains s.r.o. and contributors. Use of this source code is governed by the Apache 2.0 license.
// Copyright 2000-2025 JetBrains s.r.o. and contributors. Use of this source code is governed by the Apache 2.0 license.
package com.intellij.ui;
import com.intellij.ide.ui.UISettings;