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

#11533 Variables registry

上级 367f13a9
......@@ -32,6 +32,7 @@ Require-Bundle: org.eclipse.equinox.security,
org.eclipse.core.expressions,
org.eclipse.core.commands,
org.eclipse.core.resources,
com.google.gson,
org.eclipse.text;visibility:=reexport,
org.jkiss.dbeaver.model;visibility:=reexport
Bundle-Localization: OSGI-INF/l10n/bundle
......
......@@ -281,20 +281,35 @@ public class SQLScriptContext implements DBCScriptContext {
// Persistence
public void loadVariables(DBPDriver driver, DBPDataSourceContainer dataSource) {
variables.clear();
List<VariableInfo> varList;
if (dataSource != null) {
varList = SQLVariablesRegistry.getInstance().getDataSourceVariables(dataSource);
} else if (driver != null) {
varList = SQLVariablesRegistry.getInstance().getDriverVariables(driver);
} else {
varList = new ArrayList<>();
synchronized (variables) {
variables.clear();
List<VariableInfo> varList;
if (dataSource != null) {
varList = SQLVariablesRegistry.getInstance().getDataSourceVariables(dataSource);
} else if (driver != null) {
varList = SQLVariablesRegistry.getInstance().getDriverVariables(driver);
} else {
varList = new ArrayList<>();
}
for (VariableInfo v : varList) {
variables.put(v.name, v);
}
}
}
public void saveVariables(DBPDriver driver, DBPDataSourceContainer dataSource) {
SQLVariablesRegistry.getInstance().updateVariables(driver, dataSource, new ArrayList<>(variables.values()));
ArrayList<VariableInfo> vCopy;
synchronized (variables) {
vCopy = new ArrayList<>(this.variables.values());
}
SQLVariablesRegistry.getInstance().updateVariables(driver, dataSource, vCopy);
}
public void clearVariables() {
synchronized (variables) {
variables.clear();
}
}
////////////////////////////////////////////////////
......
......@@ -19,6 +19,8 @@ package org.jkiss.dbeaver.model.sql.registry;
import com.google.gson.Gson;
import com.google.gson.GsonBuilder;
import org.eclipse.core.runtime.IStatus;
import org.eclipse.core.runtime.Status;
import org.jkiss.code.NotNull;
import org.jkiss.code.Nullable;
import org.jkiss.dbeaver.Log;
......@@ -26,8 +28,12 @@ import org.jkiss.dbeaver.model.DBPDataSourceContainer;
import org.jkiss.dbeaver.model.connection.DBPDriver;
import org.jkiss.dbeaver.model.data.json.JSONUtils;
import org.jkiss.dbeaver.model.exec.DBCScriptContext;
import org.jkiss.dbeaver.model.runtime.AbstractJob;
import org.jkiss.dbeaver.model.runtime.DBRProgressMonitor;
import org.jkiss.dbeaver.model.sql.internal.SQLModelActivator;
import org.jkiss.dbeaver.runtime.DBWorkbench;
import org.jkiss.utils.CommonUtils;
import org.jkiss.utils.IOUtils;
import java.io.*;
import java.nio.charset.StandardCharsets;
......@@ -40,6 +46,7 @@ public class SQLVariablesRegistry {
public static final String CONFIG_FILE_SUFFIX = ".json"; //$NON-NLS-1$
public static final String CONFIG_FILE_TYPE_DRIVER = "driver"; //$NON-NLS-1$
public static final String CONFIG_FILE_TYPE_CONNECTION = "con"; //$NON-NLS-1$
public static final String VARIABLES_STORE_DIR = "variables";
private static final Gson CONFIG_GSON = new GsonBuilder()
.setLenient()
......@@ -49,7 +56,10 @@ public class SQLVariablesRegistry {
private static SQLVariablesRegistry registry;
private final Map<DBPDriver, List<DBCScriptContext.VariableInfo>> driverVariables = new HashMap<>();
private final Map<DBPDataSourceContainer, List<DBCScriptContext.VariableInfo>> connectionVariables = new HashMap<>();
private final Map<String, List<DBCScriptContext.VariableInfo>> connectionVariables = new HashMap<>();
private ConfigSaver configSaver;
private final List<Object> saveLock = new ArrayList<>();
private SQLVariablesRegistry() {
}
......@@ -74,36 +84,32 @@ public class SQLVariablesRegistry {
log.debug("Skip variables config: bad file extension (" + configFile.getAbsolutePath() + ")");
continue;
}
configName = configName.substring(CONFIG_FILE_PREFIX.length(), configName.length() - CONFIG_FILE_SUFFIX.length());
String driverId = null, conId = null;
if (configName.startsWith(CONFIG_FILE_TYPE_DRIVER)) {
driverId = configName.substring(CONFIG_FILE_TYPE_DRIVER.length() + 1);
} else if (configName.startsWith(CONFIG_FILE_TYPE_CONNECTION)) {
conId = configName.substring(CONFIG_FILE_TYPE_DRIVER.length() + 1);
} else {
log.debug("Skip variables config: unrecognized variables target (" + configFile.getAbsolutePath() + ")");
continue;
}
// configName = configName.substring(CONFIG_FILE_PREFIX.length(), configName.length() - CONFIG_FILE_SUFFIX.length());
// String driverId = null, conId = null;
// if (configName.startsWith(CONFIG_FILE_TYPE_DRIVER)) {
// driverId = configName.substring(CONFIG_FILE_TYPE_DRIVER.length() + 1);
// } else if (configName.startsWith(CONFIG_FILE_TYPE_CONNECTION)) {
// conId = configName.substring(CONFIG_FILE_TYPE_DRIVER.length() + 1);
// } else {
// log.debug("Skip variables config: unrecognized variables target (" + configFile.getAbsolutePath() + ")");
// continue;
// }
List<DBCScriptContext.VariableInfo> variables = loadVariablesFromFile(configFile);
if (driverId != null) {
DBPDriver driver = null;
driverVariables.put(driver, variables);
} else {
DBPDataSourceContainer dataSource = null;
connectionVariables.put(dataSource, variables);
}
loadVariablesFromFile(configFile);
}
}
private List<DBCScriptContext.VariableInfo> loadVariablesFromFile(File file) {
private void loadVariablesFromFile(File file) {
try (InputStream is = new FileInputStream(file)) {
try (Reader r = new InputStreamReader(is, StandardCharsets.UTF_8)) {
Map<String, Object> map = JSONUtils.parseMap(CONFIG_GSON, r);
String driverId = JSONUtils.getString(map, "driver");
String dataSourceId = JSONUtils.getString(map, "datasource");
Map<String, Object> varSrc = JSONUtils.getObject(map, "variables");
List<DBCScriptContext.VariableInfo> variables = new ArrayList<>();
for (Map.Entry<String, Object> entry : map.entrySet()) {
for (Map.Entry<String, Object> entry : varSrc.entrySet()) {
DBCScriptContext.VariableInfo variableInfo;
if (entry.getValue() instanceof Map) {
Map<String, Object> valueMap = (Map<String, Object>) entry.getValue();
......@@ -127,16 +133,29 @@ public class SQLVariablesRegistry {
variables.add(variableInfo);
}
return variables;
// Map<String, DBCScriptContext.VariableInfo> varMap = new LinkedHashMap<>();
// for (DBCScriptContext.VariableInfo v : variables) {
// varMap.put(v.name, v);
// }
if (driverId != null) {
DBPDriver driver = DBWorkbench.getPlatform().getDataSourceProviderRegistry().findDriver(driverId);
if (driver == null) {
log.debug("Driver '" + driverId + "' not found. Saved variables ignored (" + file.getAbsolutePath() + ")");
} else {
this.driverVariables.put(driver, variables);
}
} else if (dataSourceId != null) {
this.connectionVariables.put(dataSourceId, variables);
}
}
} catch (IOException e) {
log.error(e);
return Collections.emptyList();
}
}
private File getConfigLocation() {
return SQLModelActivator.getInstance().getStateLocation().toFile();
return new File(SQLModelActivator.getInstance().getStateLocation().toFile(), VARIABLES_STORE_DIR);
}
@NotNull
......@@ -161,6 +180,123 @@ public class SQLVariablesRegistry {
@Nullable DBPDataSourceContainer dataSource,
@NotNull List<DBCScriptContext.VariableInfo> variables)
{
if (dataSource != null) {
List<DBCScriptContext.VariableInfo> vars = connectionVariables.get(dataSource.getId());
if (vars == null) {
connectionVariables.put(dataSource.getId(), new ArrayList<>(variables));
} else {
vars.addAll(variables);
}
} else if (driver != null) {
List<DBCScriptContext.VariableInfo> vars = driverVariables.get(driver.getId());
if (vars == null) {
driverVariables.put(driver, new ArrayList<>(variables));
} else {
vars.addAll(variables);
}
}
saveConfig(driver, dataSource);
}
void saveConfig(@Nullable DBPDriver driver,
@Nullable DBPDataSourceContainer dataSource)
{
synchronized (saveLock) {
if (configSaver != null) {
configSaver.cancel();
configSaver = null;
}
if (driver != null && !saveLock.contains(driver)) saveLock.add(driver);
if (dataSource != null && !saveLock.contains(dataSource)) saveLock.add(dataSource);
configSaver = new ConfigSaver();
configSaver.schedule(1000);
}
}
private class ConfigSaver extends AbstractJob {
ConfigSaver() {
super("Tab folders configuration save");
setSystem(true);
}
@Override
protected IStatus run(DBRProgressMonitor monitor) {
List<Object> toSave;
synchronized (saveLock) {
toSave = new ArrayList<>(saveLock);
saveLock.clear();
}
flushConfig(toSave);
return Status.OK_STATUS;
}
private void flushConfig(List<Object> toSave) {
File configLocation = getConfigLocation();
if (!configLocation.exists()) {
if (!configLocation.mkdirs()) {
log.error("Error creating variables storage location: " + configLocation.getAbsolutePath());
return;
}
}
for (Object so : toSave) {
DBPDriver driver = null;
DBPDataSourceContainer con = null;
String fileName;
if (so instanceof DBPDriver) {
driver = (DBPDriver) so;
fileName = CONFIG_FILE_PREFIX + CONFIG_FILE_TYPE_DRIVER + "-" + driver.getFullId() + CONFIG_FILE_SUFFIX;
} else if (so instanceof DBPDataSourceContainer) {
con = (DBPDataSourceContainer)so;
fileName = CONFIG_FILE_PREFIX + CONFIG_FILE_TYPE_CONNECTION + "-" + ((DBPDataSourceContainer) so).getId() + CONFIG_FILE_SUFFIX;
} else {
continue;
}
fileName = CommonUtils.escapeFileName(fileName);
File configFile = new File(configLocation, fileName);
saveConfigToFile(configFile, driver, con);
}
}
private void saveConfigToFile(File configFile, DBPDriver driver, DBPDataSourceContainer con) {
Map<String, Object> map = new LinkedHashMap<>();
List<DBCScriptContext.VariableInfo> variables;
if (driver != null) {
map.put("driver", driver.getFullId());
variables = driverVariables.get(driver);
} else if (con != null) {
map.put("datasource", con.getId());
variables = connectionVariables.get(con.getId());
} else {
log.debug("Both driver and connection are null");
return;
}
if (CommonUtils.isEmpty(variables)) {
return;
}
Map<String, Object> varMap = new LinkedHashMap<>();
for (DBCScriptContext.VariableInfo v : variables) {
if (v.type == DBCScriptContext.VariableType.VARIABLE) {
varMap.put(v.name, v.value);
} else {
Map<String, Object> varDetails = new LinkedHashMap<>();
varDetails.put("type", v.type.name());
varDetails.put("value", v.value);
varMap.put(v.name, varDetails);
}
}
map.put("variables", varMap);
try {
IOUtils.writeFileFromString(configFile, CONFIG_GSON.toJson(map, Map.class));
} catch (IOException e) {
log.error(e);
}
}
}
......
......@@ -1789,6 +1789,30 @@ public class SQLEditor extends SQLEditorBase implements
EditorUtils.getLocalFileFromInput(getEditorInput()),
new OutputLogWriter(),
new SQLEditorParametersProvider(getSite()));
this.globalScriptContext.addListener(new DBCScriptContextListener() {
@Override
public void variableChanged(ContextAction action, DBCScriptContext.VariableInfo variable) {
saveContextVariables();
}
@Override
public void parameterChanged(ContextAction action, String name, Object value) {
saveContextVariables();
}
private void saveContextVariables() {
new AbstractJob("Save variables") {
@Override
protected IStatus run(DBRProgressMonitor monitor) {
DBPDataSourceContainer ds = getDataSourceContainer();
if (ds != null) {
globalScriptContext.saveVariables(ds.getDriver(), null);
}
return Status.OK_STATUS;
}
}.schedule(200);
}
});
}
@Override
......@@ -2469,7 +2493,8 @@ public class SQLEditor extends SQLEditorBase implements
reloadSyntaxRules();
}
if (getDataSourceContainer() == null) {
DBPDataSourceContainer dataSourceContainer = getDataSourceContainer();
if (dataSourceContainer == null) {
resultsSash.setMaximizedControl(sqlEditorPanel);
} else {
if (curQueryProcessor != null && curQueryProcessor.getFirstResults().hasData()) {
......@@ -2481,6 +2506,12 @@ public class SQLEditor extends SQLEditorBase implements
syntaxLoaded = true;
loadActivePreferenceSettings();
if (dataSourceContainer != null) {
globalScriptContext.loadVariables(dataSourceContainer.getDriver(), null);
} else {
globalScriptContext.clearVariables();
}
}
@Override
......
Markdown is supported
0% .
You are about to add 0 people to the discussion. Proceed with caution.
先完成此消息的编辑!
想要评论请 注册