提交 19365685 编写于 作者: S Serge Rider

#1562 Transaction management menu refactoring. Smart auto-commit option.

上级 274e1565
......@@ -42,6 +42,7 @@ public class CoreMessages extends NLS {
public static String action_menu_transaction_autocommit_name;
public static String action_menu_transaction_manualcommit_description;
public static String action_menu_transaction_autocommit_description;
public static String action_menu_transaction_smart_auto_commit;
public static String action_menu_tools_find_in_navigator;
public static String action_menu_transactionMonitor_totalStatement;
......
......@@ -33,6 +33,7 @@ action_menu_transaction_autocommit_name = Switch to auto-commit
action_menu_transaction_autocommit_description = Auto-Commit
action_menu_transaction_manualcommit_name = Switch to manual commit ({0})
action_menu_transaction_manualcommit_description = Manual Commit ({0})
action_menu_transaction_smart_auto_commit = Smart auto-commit
action_menu_tools_find_in_navigator = Find in Navigator
## Confirmations ##
......
......@@ -16,58 +16,54 @@
*/
package org.jkiss.dbeaver.ui.actions.datasource;
import org.eclipse.core.runtime.IStatus;
import org.eclipse.core.runtime.Status;
import org.eclipse.jface.action.Action;
import org.eclipse.jface.action.IContributionItem;
import org.eclipse.jface.action.Separator;
import org.eclipse.osgi.util.NLS;
import org.eclipse.ui.IEditorPart;
import org.eclipse.ui.IWorkbenchWindow;
import org.eclipse.ui.menus.CommandContributionItem;
import org.jkiss.dbeaver.DBException;
import org.jkiss.dbeaver.Log;
import org.jkiss.dbeaver.core.CoreCommands;
import org.jkiss.dbeaver.core.CoreMessages;
import org.jkiss.dbeaver.model.*;
import org.jkiss.dbeaver.model.exec.DBCException;
import org.jkiss.dbeaver.model.exec.DBCExecutionContext;
import org.jkiss.dbeaver.model.exec.DBCTransactionManager;
import org.jkiss.dbeaver.runtime.DBWorkbench;
import org.jkiss.dbeaver.model.runtime.AbstractJob;
import org.jkiss.dbeaver.model.runtime.DBRProgressMonitor;
import org.jkiss.dbeaver.ui.ActionUtils;
import org.jkiss.dbeaver.ui.UIUtils;
import org.jkiss.dbeaver.ui.actions.AbstractDataSourceHandler;
import org.jkiss.dbeaver.utils.GeneralUtils;
import org.jkiss.utils.CommonUtils;
import java.util.List;
public class DataSourceTransactionModeContributor extends DataSourceMenuContributor
{
public class DataSourceTransactionModeContributor extends DataSourceMenuContributor {
private static final Log log = Log.getLog(DataSourceTransactionModeContributor.class);
@Override
protected void fillContributionItems(final List<IContributionItem> menuItems)
{
IWorkbenchWindow window = UIUtils.getActiveWorkbenchWindow();
if (window == null) {
return;
}
IEditorPart activePart = window.getActivePage().getActiveEditor();
DBPDataSourceContainer container = AbstractDataSourceHandler.getDataSourceContainer(activePart);
protected void fillContributionItems(final List<IContributionItem> menuItems) {
IEditorPart activePart = UIUtils.getActiveWorkbenchWindow().getActivePage().getActiveEditor();
DBCExecutionContext executionContext = AbstractDataSourceHandler.getExecutionContext(activePart);
DBPDataSource dataSource = null;
if (container != null) {
dataSource = container.getDataSource();
if (executionContext != null) {
dataSource = executionContext.getDataSource();
}
if (dataSource == null) {
return;
}
final DBPDataSourceInfo dsInfo = dataSource.getInfo();
DBCTransactionManager txnManager = DBUtils.getTransactionManager(DBUtils.getDefaultContext(dataSource, false));
DBCTransactionManager txnManager = DBUtils.getTransactionManager(executionContext);
if (txnManager != null) {
menuItems.add(ActionUtils.makeCommandContribution(
window,
CoreCommands.CMD_TOGGLE_AUTOCOMMIT,
CommandContributionItem.STYLE_CHECK));
menuItems.add(new Separator());
boolean autoCommit = false;
try {
autoCommit = txnManager.isAutoCommit();
} catch (DBCException e) {
log.warn("Can't determine current auto-commit mode", e);
}
// Transactions
DBPTransactionIsolation txnLevelCurrent = null;
try {
......@@ -75,61 +71,155 @@ public class DataSourceTransactionModeContributor extends DataSourceMenuContribu
} catch (DBCException ex) {
log.warn("Can't determine current transaction isolation level", ex);
}
menuItems.add(ActionUtils.makeActionContribution(
new TransactionAutoCommitAction(executionContext, true, autoCommit, txnLevelCurrent),
true));
menuItems.add(ActionUtils.makeActionContribution(
new TransactionAutoCommitAction(executionContext, false, !autoCommit, txnLevelCurrent),
true));
if (activePart instanceof ISmartTransactionManager) {
menuItems.add(ActionUtils.makeActionContribution(
new SmartAutoCommitAction((ISmartTransactionManager)activePart),
true));
}
menuItems.add(new Separator());
for (DBPTransactionIsolation txi : CommonUtils.safeCollection(dsInfo.getSupportedTransactionsIsolation())) {
if (!txi.isEnabled()) {
continue;
}
menuItems.add(ActionUtils.makeActionContribution(
new TransactionIsolationAction(dataSource, txi, txi.equals(txnLevelCurrent)),
true));
new TransactionIsolationAction(executionContext, txi, txi.equals(txnLevelCurrent)),
true));
}
}
}
private static class TransactionIsolationAction extends Action
{
private static class TransactionAutoCommitAction extends Action {
private final DBCExecutionContext executionContext;
private final boolean autoCommit;
private final DBPTransactionIsolation isolation;
private final DBPDataSource dataSource;
private final DBPTransactionIsolation level;
private final boolean checked;
public TransactionIsolationAction(DBPDataSource dataSource, DBPTransactionIsolation level, boolean checked)
{
this.dataSource = dataSource;
this.level = level;
this.checked = checked;
public TransactionAutoCommitAction(DBCExecutionContext executionContext, boolean autoCommit, boolean enabled, DBPTransactionIsolation isolation) {
this.executionContext = executionContext;
this.autoCommit = autoCommit;
this.isolation = isolation;
setChecked(enabled);
}
@Override
public int getStyle()
{
public int getStyle() {
return AS_RADIO_BUTTON;
}
@Override
public boolean isChecked()
{
return checked;
public String getText() {
String isolationName = isolation == null ? "?" : isolation.getTitle();
return autoCommit ? CoreMessages.action_menu_transaction_autocommit_description : NLS.bind(CoreMessages.action_menu_transaction_manualcommit_description, isolationName);
}
@Override
public void run() {
if (!isChecked()) {
return;
}
DBCTransactionManager txnManager = DBUtils.getTransactionManager(executionContext);
if (txnManager != null) {
new AbstractJob("Set auto-commit") {
@Override
protected IStatus run(DBRProgressMonitor monitor) {
monitor.beginTask("Change connection auto-commit to " + autoCommit, 1);
try {
monitor.subTask("Change context '" + executionContext.getContextName() + "' auto-commit state");
txnManager.setAutoCommit(monitor, autoCommit);
} catch (Exception e) {
return GeneralUtils.makeExceptionStatus(e);
} finally {
monitor.done();
}
return Status.OK_STATUS;
}
}.schedule();
}
}
}
private static class SmartAutoCommitAction extends Action {
private final ISmartTransactionManager smartTransactionManager;
public SmartAutoCommitAction(ISmartTransactionManager smartTransactionManager) {
this.smartTransactionManager = smartTransactionManager;
setChecked(smartTransactionManager.isSmartAutoCommit());
}
@Override
public int getStyle() {
return AS_CHECK_BOX;
}
@Override
public String getText() {
return CoreMessages.action_menu_transaction_smart_auto_commit;
}
@Override
public boolean isChecked() {
return smartTransactionManager.isSmartAutoCommit();
}
@Override
public void run() {
smartTransactionManager.setSmartAutoCommit(!smartTransactionManager.isSmartAutoCommit());
}
}
private static class TransactionIsolationAction extends Action {
private final DBCExecutionContext executionContext;
private final DBPTransactionIsolation level;
public TransactionIsolationAction(DBCExecutionContext executionContext, DBPTransactionIsolation level, boolean checked) {
this.executionContext = executionContext;
this.level = level;
setChecked(checked);
}
@Override
public String getText()
{
public int getStyle() {
return AS_RADIO_BUTTON;
}
@Override
public String getText() {
return level.getTitle();
}
@Override
public void run()
{
try {
dataSource.getContainer().setDefaultTransactionsIsolation(level);
} catch (DBException e) {
DBWorkbench.getPlatformUI().showError(
"Transactions Isolation",
"Can't set transaction isolation level to '" + level + "'",
e);
public void run() {
if (!isChecked()) {
return;
}
dataSource.getContainer().persistConfiguration();
DBCTransactionManager txnManager = DBUtils.getTransactionManager(executionContext);
if (txnManager != null) {
new AbstractJob("Set transaction isolation level") {
@Override
protected IStatus run(DBRProgressMonitor monitor) {
monitor.beginTask("Change transaction isolation level to " + level.getTitle(), 1);
try {
monitor.subTask("Change context '" + executionContext.getContextName() + "' transaction isolation level");
txnManager.setTransactionIsolation(monitor, level);
executionContext.getDataSource().getContainer().setDefaultTransactionsIsolation(level);
executionContext.getDataSource().getContainer().persistConfiguration();
} catch (Exception e) {
return GeneralUtils.makeExceptionStatus(e);
} finally {
monitor.done();
}
return Status.OK_STATUS;
}
}.schedule();
}
}
}
......
......@@ -326,18 +326,14 @@ class ConnectionPageInitialization extends ConnectionWizardPage implements IData
// No changes anyway
return;
}
try {
dataSource.setDefaultAutoCommit(autocommit.getSelection());
if (txnOptionsLoaded) {
int levelIndex = isolationLevel.getSelectionIndex();
if (levelIndex <= 0) {
dataSource.setDefaultTransactionsIsolation(null);
} else {
dataSource.setDefaultTransactionsIsolation(supportedLevels.get(levelIndex - 1));
}
dataSource.setDefaultAutoCommit(autocommit.getSelection());
if (txnOptionsLoaded) {
int levelIndex = isolationLevel.getSelectionIndex();
if (levelIndex <= 0) {
dataSource.setDefaultTransactionsIsolation(null);
} else {
dataSource.setDefaultTransactionsIsolation(supportedLevels.get(levelIndex - 1));
}
} catch (DBException e) {
log.error(e);
}
final DBPConnectionConfiguration confConfig = dataSource.getConnectionConfiguration();
DBPConnectionBootstrap bootstrap = confConfig.getBootstrap();
......
......@@ -174,7 +174,7 @@ class StreamDataSourceContainer implements DBPDataSourceContainer {
}
@Override
public void setDefaultTransactionsIsolation(DBPTransactionIsolation isolationLevel) throws DBException {
public void setDefaultTransactionsIsolation(DBPTransactionIsolation isolationLevel) {
}
......
......@@ -109,8 +109,7 @@ public interface DBPDataSourceContainer extends DBSObject, DBDPreferences, DBPNa
@Nullable
Integer getDefaultTransactionsIsolation();
void setDefaultTransactionsIsolation(DBPTransactionIsolation isolationLevel)
throws DBException;
void setDefaultTransactionsIsolation(DBPTransactionIsolation isolationLevel);
/**
* Search for object filter which corresponds specified object type and parent object.
......
......@@ -14,13 +14,16 @@
* See the License for the specific language governing permissions and
* limitations under the License.
*/
package org.jkiss.dbeaver.model;
/**
* Auto-commit mode
* Smart transaction manager
*/
public enum DBPAutoCommitMode {
ON,
OFF,
SMART
}
public interface ISmartTransactionManager {
boolean isSmartAutoCommit();
void setSmartAutoCommit(boolean smartAutoCommit);
}
\ No newline at end of file
......@@ -57,13 +57,11 @@ import org.jkiss.dbeaver.registry.formatter.DataFormatterProfile;
import org.jkiss.dbeaver.registry.internal.RegistryMessages;
import org.jkiss.dbeaver.runtime.DBWorkbench;
import org.jkiss.dbeaver.runtime.IVariableResolver;
import org.jkiss.dbeaver.runtime.TasksJob;
import org.jkiss.dbeaver.runtime.properties.PropertyCollector;
import org.jkiss.dbeaver.utils.SystemVariablesResolver;
import org.jkiss.utils.CommonUtils;
import java.io.IOException;
import java.lang.reflect.InvocationTargetException;
import java.text.DateFormat;
import java.util.*;
......@@ -417,25 +415,11 @@ public class DataSourceDescriptor
}
@Override
public void setDefaultTransactionsIsolation(@Nullable final DBPTransactionIsolation isolationLevel) throws DBException {
public void setDefaultTransactionsIsolation(@Nullable final DBPTransactionIsolation isolationLevel) {
if (isolationLevel == null) {
connectionInfo.getBootstrap().setDefaultTransactionIsolation(null);
} else {
connectionInfo.getBootstrap().setDefaultTransactionIsolation(isolationLevel.getCode());
if (dataSource != null) {
TasksJob.runTask("Set transactions isolation level", monitor -> {
DBCTransactionManager txnManager = DBUtils.getTransactionManager(DBUtils.getDefaultContext(dataSource.getDefaultInstance(), false));
if (txnManager != null) {
try {
if (!txnManager.getTransactionIsolation().equals(isolationLevel)) {
txnManager.setTransactionIsolation(monitor, isolationLevel);
}
} catch (DBCException e) {
throw new InvocationTargetException(e);
}
}
});
}
}
}
......
......@@ -115,8 +115,8 @@ import org.jkiss.utils.CommonUtils;
import java.io.*;
import java.net.URI;
import java.util.*;
import java.util.List;
import java.util.*;
import java.util.concurrent.atomic.AtomicInteger;
import java.util.regex.Matcher;
import java.util.regex.Pattern;
......@@ -130,7 +130,8 @@ public class SQLEditor extends SQLEditorBase implements
ISaveablePart2,
DBPDataSourceTask,
DBPDataSourceHandler,
DBPPreferenceListener
DBPPreferenceListener,
ISmartTransactionManager
{
private static final long SCRIPT_UI_UPDATE_PERIOD = 100;
private static final int MAX_PARALLEL_QUERIES_NO_WARN = 1;
......@@ -518,6 +519,21 @@ public class SQLEditor extends SQLEditorBase implements
return getTotalQueryRunning() > 0;
}
@Override
public boolean isSmartAutoCommit() {
return getActivePreferenceStore().getBoolean(SQLPreferenceConstants.EDITOR_SMART_AUTO_COMMIT);
}
@Override
public void setSmartAutoCommit(boolean smartAutoCommit) {
getActivePreferenceStore().setValue(SQLPreferenceConstants.EDITOR_SMART_AUTO_COMMIT, smartAutoCommit);
try {
getActivePreferenceStore().save();
} catch (IOException e) {
log.error("Error saving smart auto-commit option", e);
}
}
private class OutputLogWriter extends Writer {
@Override
public void write(@NotNull final char[] cbuf, final int off, final int len) {
......
......@@ -130,6 +130,7 @@ public class SQLPreferenceConstants
public static final String EDITOR_SEPARATE_CONNECTION = "database.editor.separate.connection"; //$NON-NLS-1$
public static final String EDITOR_CONNECT_ON_ACTIVATE = "database.editor.connect.on.activate"; //$NON-NLS-1$
public static final String EDITOR_CONNECT_ON_EXECUTE = "database.editor.connect.on.execute"; //$NON-NLS-1$
public static final String EDITOR_SMART_AUTO_COMMIT = "database.editor.smart.auto.commit"; //$NON-NLS-1$
public static final String CONFIRM_DANGER_SQL = "dangerous_sql"; //$NON-NLS-1$
public static final String CONFIRM_MASS_PARALLEL_SQL = "mass_parallel_sql"; //$NON-NLS-1$
......
......@@ -114,6 +114,8 @@ public class SQLEditorMessages extends NLS {
public static String pref_page_sql_editor_label_separate_connection_each_editor;
public static String pref_page_sql_editor_label_connect_on_editor_activation;
public static String pref_page_sql_editor_label_connect_on_query_execute;
public static String pref_page_sql_editor_label_smart_auto_commit;
public static String pref_page_sql_editor_label_smart_auto_commit_tip;
public static String pref_page_sql_editor_group_auto_save;
public static String pref_page_sql_editor_label_auto_save_on_close;
......
......@@ -112,6 +112,8 @@ pref_page_sql_editor_group_connections = Connections
pref_page_sql_editor_label_separate_connection_each_editor = Open separate connection for each editor
pref_page_sql_editor_label_connect_on_editor_activation = Connect on editor activation
pref_page_sql_editor_label_connect_on_query_execute = Connect on query execute
pref_page_sql_editor_label_smart_auto_commit = Smart auto-commit
pref_page_sql_editor_label_smart_auto_commit_tip = "Smart" commit mode.\nEnables transaction before any data modifying query (e.g. INSERT, UPDATE).\nYou can configure extra keywords for transaction activation.
pref_page_sql_editor_group_auto_save = Auto-save
pref_page_sql_editor_label_auto_save_on_close = Auto-save editor on close
pref_page_sql_editor_label_save_on_query_execute = Save editor on query execute
......
......@@ -50,6 +50,7 @@ public class SQLEditorPreferencesInitializer extends AbstractPreferenceInitializ
PrefUtils.setDefaultPreferenceValue(store, SQLPreferenceConstants.EDITOR_SEPARATE_CONNECTION, true);
PrefUtils.setDefaultPreferenceValue(store, SQLPreferenceConstants.EDITOR_CONNECT_ON_ACTIVATE, true);
PrefUtils.setDefaultPreferenceValue(store, SQLPreferenceConstants.EDITOR_CONNECT_ON_EXECUTE, false);
PrefUtils.setDefaultPreferenceValue(store, SQLPreferenceConstants.EDITOR_SMART_AUTO_COMMIT, true);
{
// SQL prefs
......
......@@ -47,6 +47,7 @@ public class PrefPageSQLEditor extends TargetPrefPage
private Button editorSeparateConnectionCheck;
private Button connectOnActivationCheck;
private Button connectOnExecuteCheck;
private Button smartAutoCommitCheck;
private Button saveOnQueryExecution;
private Button autoSaveOnClose;
......@@ -100,6 +101,7 @@ public class PrefPageSQLEditor extends TargetPrefPage
connectOnActivationCheck = UIUtils.createCheckbox(connectionsGroup, SQLEditorMessages.pref_page_sql_editor_label_connect_on_editor_activation, false);
connectOnExecuteCheck = UIUtils.createCheckbox(connectionsGroup, SQLEditorMessages.pref_page_sql_editor_label_connect_on_query_execute, false);
smartAutoCommitCheck = UIUtils.createCheckbox(connectionsGroup, SQLEditorMessages.pref_page_sql_editor_label_smart_auto_commit, SQLEditorMessages.pref_page_sql_editor_label_smart_auto_commit_tip, false, 1);
}
{
......@@ -149,6 +151,7 @@ public class PrefPageSQLEditor extends TargetPrefPage
editorSeparateConnectionCheck.setSelection(store.getBoolean(SQLPreferenceConstants.EDITOR_SEPARATE_CONNECTION));
connectOnActivationCheck.setSelection(store.getBoolean(SQLPreferenceConstants.EDITOR_CONNECT_ON_ACTIVATE));
connectOnExecuteCheck.setSelection(store.getBoolean(SQLPreferenceConstants.EDITOR_CONNECT_ON_EXECUTE));
smartAutoCommitCheck.setSelection(store.getBoolean(SQLPreferenceConstants.EDITOR_SMART_AUTO_COMMIT));
autoSaveOnClose.setSelection(store.getBoolean(SQLPreferenceConstants.AUTO_SAVE_ON_CLOSE));
saveOnQueryExecution.setSelection(store.getBoolean(SQLPreferenceConstants.AUTO_SAVE_ON_EXECUTE));
......@@ -173,6 +176,7 @@ public class PrefPageSQLEditor extends TargetPrefPage
store.setValue(SQLPreferenceConstants.EDITOR_SEPARATE_CONNECTION, editorSeparateConnectionCheck.getSelection());
store.setValue(SQLPreferenceConstants.EDITOR_CONNECT_ON_ACTIVATE, connectOnActivationCheck.getSelection());
store.setValue(SQLPreferenceConstants.EDITOR_CONNECT_ON_EXECUTE, connectOnExecuteCheck.getSelection());
store.setValue(SQLPreferenceConstants.EDITOR_SMART_AUTO_COMMIT, smartAutoCommitCheck.getSelection());
store.setValue(SQLPreferenceConstants.AUTO_SAVE_ON_CLOSE, autoSaveOnClose.getSelection());
store.setValue(SQLPreferenceConstants.AUTO_SAVE_ON_EXECUTE, saveOnQueryExecution.getSelection());
......@@ -201,6 +205,7 @@ public class PrefPageSQLEditor extends TargetPrefPage
store.setToDefault(SQLPreferenceConstants.EDITOR_SEPARATE_CONNECTION);
store.setToDefault(SQLPreferenceConstants.EDITOR_CONNECT_ON_ACTIVATE);
store.setToDefault(SQLPreferenceConstants.EDITOR_CONNECT_ON_EXECUTE);
store.setToDefault(SQLPreferenceConstants.EDITOR_SMART_AUTO_COMMIT);
store.setToDefault(SQLPreferenceConstants.AUTO_SAVE_ON_CLOSE);
store.setToDefault(SQLPreferenceConstants.AUTO_SAVE_ON_EXECUTE);
......
Markdown is supported
0% .
You are about to add 0 people to the discussion. Proceed with caution.
先完成此消息的编辑!
想要评论请 注册