提交 5b482007 编写于 作者: S Serge Rider

#7853 SQL generators model refactoring. Make all generators configurable

上级 5f8728bc
......@@ -18,6 +18,34 @@
<formatter id="external" class="org.jkiss.dbeaver.model.sql.format.external.SQLFormatterExternal" label="%sql.formatter.external.name" description="%sql.formatter.external.tip"/>
</extension>
<!-- SQL Generators -->
<extension point="org.jkiss.dbeaver.sqlGenerator">
<generator id="tableSelect" class="org.jkiss.dbeaver.model.sql.generator.SQLGeneratorSelect" label="SELECT" description="SELECT from table" order="1">
<objectType name="org.jkiss.dbeaver.model.struct.DBSDataContainer"/>
</generator>
<generator id="tableInsert" class="org.jkiss.dbeaver.model.sql.generator.SQLGeneratorInsert" label="INSERT" description="INSERT into table" order="2">
<objectType name="org.jkiss.dbeaver.model.struct.DBSDataManipulator"/>
</generator>
<generator id="tableUpdate" class="org.jkiss.dbeaver.model.sql.generator.SQLGeneratorUpdate" label="UPDATE" description="UPDATE table" order="3">
<objectType name="org.jkiss.dbeaver.model.struct.DBSDataManipulator"/>
</generator>
<generator id="tableDelete" class="org.jkiss.dbeaver.model.sql.generator.SQLGeneratorDelete" label="DELETE" description="DELETE from table" order="4">
<objectType name="org.jkiss.dbeaver.model.struct.DBSDataManipulator"/>
</generator>
<generator id="tableMerge" class="org.jkiss.dbeaver.model.sql.generator.SQLGeneratorMerge" label="MERGE" description="MERGE table" order="5">
<objectType name="org.jkiss.dbeaver.model.struct.DBSDataManipulator"/>
</generator>
<generator id="tableJoin" class="org.jkiss.dbeaver.model.sql.generator.SQLGeneratorJoin" label="JOIN" description="JOIN tables" order="6" multiObject="true">
<objectType name="org.jkiss.dbeaver.model.struct.DBSDataContainer"/>
</generator>
<generator id="procedureCall" class="org.jkiss.dbeaver.model.sql.generator.SQLGeneratorProcedureCall" label="CALL" description="Execute procedure" order="1000">
<objectType name="org.jkiss.dbeaver.model.struct.rdb.DBSProcedure"/>
</generator>
<generator id="tableDDL" class="org.jkiss.dbeaver.model.sql.generator.SQLGeneratorDDL" label="DDL" description="Get table DDL" order="1001">
<objectType name="org.jkiss.dbeaver.model.DBPScriptObject"/>
</generator>
</extension>
<extension point="org.jkiss.dbeaver.sqlCommand">
<command id="set" class="org.jkiss.dbeaver.model.sql.commands.SQLCommandSet" label="Set" description="Sets variable/parameter value"/>
<command id="unset" class="org.jkiss.dbeaver.model.sql.commands.SQLCommandUnset" label="Unset" description="Removes variable/parameter"/>
......
......@@ -28,10 +28,6 @@ import java.util.List;
public abstract class BaseAnalysisRunner<OBJECT> extends SQLGenerator<OBJECT> {
protected BaseAnalysisRunner(List<OBJECT> objects) {
super(objects);
}
protected abstract Collection<? extends DBSAttributeBase> getAllAttributes(DBRProgressMonitor monitor, OBJECT object) throws DBException;
protected abstract Collection<? extends DBSAttributeBase> getKeyAttributes(DBRProgressMonitor monitor, OBJECT object) throws DBException;
......
......@@ -22,15 +22,9 @@ import org.jkiss.dbeaver.model.struct.rdb.DBSProcedure;
import java.util.Collection;
import java.util.Collections;
import java.util.List;
public abstract class ProcedureAnalysisRunner extends BaseAnalysisRunner<DBSProcedure> {
ProcedureAnalysisRunner(List<DBSProcedure> entities)
{
super(entities);
}
protected Collection<? extends DBSEntityAttribute> getAllAttributes(DBRProgressMonitor monitor, DBSProcedure object) {
return Collections.emptyList();
}
......
......@@ -29,15 +29,18 @@ import java.util.List;
import java.util.Map;
public abstract class SQLGenerator<OBJECT> extends DBRRunnableWithResult<String> {
final protected List<OBJECT> objects;
protected List<OBJECT> objects;
private boolean fullyQualifiedNames = true;
private boolean compactSQL = false;
SQLGenerator(List<OBJECT> objects)
{
public void initGenerator(List<OBJECT> objects) {
this.objects = objects;
}
public List<OBJECT> getObjects() {
return objects;
}
public boolean isFullyQualifiedNames() {
return fullyQualifiedNames;
}
......
......@@ -32,9 +32,6 @@ import java.util.List;
import java.util.Map;
public class SQLGeneratorDDL extends SQLGenerator<DBPScriptObject> {
public SQLGeneratorDDL(List<DBPScriptObject> scriptObjects) {
super(scriptObjects);
}
@Override
public void run(DBRProgressMonitor monitor) throws InvocationTargetException, InterruptedException {
......
......@@ -25,12 +25,8 @@ import org.jkiss.dbeaver.model.struct.DBSEntityAttribute;
import org.jkiss.utils.CommonUtils;
import java.util.Collection;
import java.util.List;
public class SQLGeneratorDelete extends TableAnalysisRunner {
public SQLGeneratorDelete(List<DBSEntity> entities) {
super(entities);
}
@Override
public void generateSQL(DBRProgressMonitor monitor, StringBuilder sql, DBSEntity object) throws DBException {
......
......@@ -23,12 +23,7 @@ import org.jkiss.dbeaver.model.runtime.DBRProgressMonitor;
import org.jkiss.dbeaver.model.struct.DBSEntity;
import org.jkiss.dbeaver.model.struct.DBSEntityAttribute;
import java.util.List;
public class SQLGeneratorInsert extends TableAnalysisRunner {
public SQLGeneratorInsert(List<DBSEntity> entities) {
super(entities);
}
@Override
public void generateSQL(DBRProgressMonitor monitor, StringBuilder sql, DBSEntity object) throws DBException {
......
......@@ -22,14 +22,9 @@ import org.jkiss.dbeaver.model.sql.SQLUtils;
import org.jkiss.dbeaver.model.struct.DBSEntity;
import java.lang.reflect.InvocationTargetException;
import java.util.List;
public class SQLGeneratorJoin extends SQLGenerator<DBSEntity> {
public SQLGeneratorJoin(List<DBSEntity> entities) {
super(entities);
}
@Override
public void run(DBRProgressMonitor monitor) throws InvocationTargetException {
StringBuilder sql = new StringBuilder(100);
......
......@@ -25,12 +25,8 @@ import org.jkiss.dbeaver.model.struct.DBSEntityAttribute;
import org.jkiss.utils.CommonUtils;
import java.util.Collection;
import java.util.List;
public class SQLGeneratorMerge extends TableAnalysisRunner {
public SQLGeneratorMerge(List<DBSEntity> entities) {
super(entities);
}
@Override
public void generateSQL(DBRProgressMonitor monitor, StringBuilder sql, DBSEntity object) throws DBException {
......
......@@ -25,14 +25,9 @@ import org.jkiss.dbeaver.model.struct.rdb.DBSProcedureParameter;
import org.jkiss.utils.CommonUtils;
import java.util.Collection;
import java.util.List;
public class SQLGeneratorProcedureCall extends ProcedureAnalysisRunner {
public SQLGeneratorProcedureCall(List<DBSProcedure> entities) {
super(entities);
}
@Override
protected void generateSQL(DBRProgressMonitor monitor, StringBuilder sql, DBSProcedure proc) throws DBException {
Collection<? extends DBSProcedureParameter> parameters = proc.getParameters(monitor);
......
......@@ -23,13 +23,10 @@ import org.jkiss.dbeaver.model.runtime.DBRProgressMonitor;
import org.jkiss.dbeaver.model.struct.DBSEntity;
import org.jkiss.dbeaver.model.struct.DBSEntityAttribute;
import java.util.List;
public class SQLGeneratorSelect extends TableAnalysisRunner {
private final boolean columnList;
private boolean columnList;
public SQLGeneratorSelect(List<DBSEntity> entities, boolean columnList) {
super(entities);
public void setColumnList(boolean columnList) {
this.columnList = columnList;
}
......
......@@ -26,12 +26,8 @@ import org.jkiss.dbeaver.model.struct.DBSEntityAttribute;
import org.jkiss.utils.CommonUtils;
import java.util.Collection;
import java.util.List;
public class SQLGeneratorUpdate extends TableAnalysisRunner {
public SQLGeneratorUpdate(List<DBSEntity> entities) {
super(entities);
}
@Override
public void generateSQL(DBRProgressMonitor monitor, StringBuilder sql, DBSEntity object) throws DBException {
......
......@@ -24,15 +24,9 @@ import org.jkiss.dbeaver.model.struct.DBSEntityAttribute;
import org.jkiss.utils.CommonUtils;
import java.util.Collection;
import java.util.List;
public abstract class TableAnalysisRunner extends BaseAnalysisRunner<DBSEntity> {
TableAnalysisRunner(List<DBSEntity> entities)
{
super(entities);
}
protected Collection<? extends DBSEntityAttribute> getAllAttributes(DBRProgressMonitor monitor, DBSEntity object) throws DBException
{
return CommonUtils.safeCollection(object.getAttributes(monitor));
......
......@@ -22,16 +22,19 @@ import org.eclipse.core.runtime.Platform;
import org.jkiss.code.Nullable;
import org.jkiss.dbeaver.Log;
import org.jkiss.dbeaver.model.DBPDataSource;
import org.jkiss.dbeaver.model.DBPObject;
import org.jkiss.dbeaver.model.sql.generator.SQLGenerator;
import java.util.ArrayList;
import java.util.Collection;
import java.util.Comparator;
import java.util.List;
public class SQLGeneratorConfigurationRegistry
{
private static final Log log = Log.getLog(SQLGeneratorConfigurationRegistry.class);
private static final String TAG_FORMATTER = "generator"; //$NON-NLS-1$
private static final String TAG_GENERATOR = "generator"; //$NON-NLS-1$
private static SQLGeneratorConfigurationRegistry instance = null;
private final List<SQLGeneratorDescriptor> generators = new ArrayList<>();
......@@ -51,10 +54,10 @@ public class SQLGeneratorConfigurationRegistry
private void loadExtensions(IExtensionRegistry registry)
{
IConfigurationElement[] extConfigs = registry.getConfigurationElementsFor(SQLFormatterDescriptor.EXTENSION_ID);
IConfigurationElement[] extConfigs = registry.getConfigurationElementsFor(SQLGeneratorDescriptor.EXTENSION_ID);
for (IConfigurationElement ext : extConfigs) {
// Load generators
if (TAG_FORMATTER.equals(ext.getName())) {
if (TAG_GENERATOR.equals(ext.getName())) {
this.generators.add(
new SQLGeneratorDescriptor(ext));
}
......@@ -70,8 +73,21 @@ public class SQLGeneratorConfigurationRegistry
return new ArrayList<>(generators);
}
public List<SQLGeneratorDescriptor> getApplicableGenerators() {
return getAllGenerators();
public List<SQLGeneratorDescriptor> getApplicableGenerators(Collection<?> objects, Object context) {
List<SQLGeneratorDescriptor> result = new ArrayList<>();
for (SQLGeneratorDescriptor gen : generators) {
for (Object object : objects) {
if (object instanceof DBPObject && gen.appliesTo((DBPObject) object, context)) {
if (gen.isMultiObject() && objects.size() < 2) {
continue;
}
result.add(gen);
break;
}
}
}
result.sort(Comparator.comparingInt(SQLGeneratorDescriptor::getOrder));
return result;
}
public SQLGeneratorDescriptor getGenerator(String id) {
......
......@@ -20,9 +20,9 @@ package org.jkiss.dbeaver.model.sql.registry;
import org.eclipse.core.runtime.IConfigurationElement;
import org.jkiss.code.NotNull;
import org.jkiss.dbeaver.DBException;
import org.jkiss.dbeaver.model.DBPDataSource;
import org.jkiss.dbeaver.model.impl.AbstractContextDescriptor;
import org.jkiss.dbeaver.model.sql.generator.SQLGenerator;
import org.jkiss.utils.CommonUtils;
import java.util.List;
......@@ -36,14 +36,18 @@ public class SQLGeneratorDescriptor extends AbstractContextDescriptor {
private final String id;
private final String label;
private final String description;
private final int order;
private final boolean multiObject;
private final ObjectType generatorImplClass;
public SQLGeneratorDescriptor(IConfigurationElement config) {
SQLGeneratorDescriptor(IConfigurationElement config) {
super(config);
this.id = config.getAttribute("id");
this.label = config.getAttribute("label");
this.description = config.getAttribute("description");
this.generatorImplClass = new ObjectType(config.getAttribute("class"));
this.order = CommonUtils.toInt(config.getAttribute("order"));
this.multiObject = CommonUtils.toBoolean(config.getAttribute("multiObject"));
}
public String getId() {
......@@ -58,12 +62,26 @@ public class SQLGeneratorDescriptor extends AbstractContextDescriptor {
return description;
}
public int getOrder() {
return order;
}
public boolean isMultiObject() {
return multiObject;
}
@NotNull
public <T> SQLGenerator<T> createGenerator(DBPDataSource dataSource, List<T> objects)
throws DBException {
SQLGenerator instance = generatorImplClass.createInstance(SQLGenerator.class);
//instance.ini
public <T> SQLGenerator<T> createGenerator(List<T> objects)
throws DBException
{
@SuppressWarnings("unchecked")
SQLGenerator<T> instance = generatorImplClass.createInstance(SQLGenerator.class);
instance.initGenerator(objects);
return instance;
}
@Override
public String toString() {
return id;
}
}
......@@ -29,6 +29,7 @@ Export-Package: org.jkiss.dbeaver.registry.functions,
org.jkiss.dbeaver.ui.controls,
org.jkiss.dbeaver.ui.controls.lightgrid,
org.jkiss.dbeaver.ui.controls.resultset,
org.jkiss.dbeaver.ui.controls.resultset.generator,
org.jkiss.dbeaver.ui.controls.resultset.internal,
org.jkiss.dbeaver.ui.controls.resultset.plaintext,
org.jkiss.dbeaver.ui.controls.resultset.spreadsheet,
......
......@@ -180,6 +180,25 @@
</editor>
</extension>
<!-- SQL Generators -->
<extension point="org.jkiss.dbeaver.sqlGenerator">
<generator id="dataSelect" class="org.jkiss.dbeaver.ui.controls.resultset.generator.SQLGeneratorSelectFromData" label="SELECT .. WHERE .. =" description="SELECT from table" order="1">
<objectType name="org.jkiss.dbeaver.ui.controls.resultset.IResultSetController"/>
</generator>
<generator id="dataSelectMany" class="org.jkiss.dbeaver.ui.controls.resultset.generator.SQLGeneratorSelectManyFromData" label="SELECT .. WHERE .. IN" description="SELECT from table IN" order="2" multiObject="true">
<objectType name="org.jkiss.dbeaver.ui.controls.resultset.IResultSetController"/>
</generator>
<generator id="dataInsert" class="org.jkiss.dbeaver.ui.controls.resultset.generator.SQLGeneratorInsertFromData" label="INSERT" description="INSERT into table" order="3">
<objectType name="org.jkiss.dbeaver.ui.controls.resultset.IResultSetController"/>
</generator>
<generator id="dataUpdate" class="org.jkiss.dbeaver.ui.controls.resultset.generator.SQLGeneratorUpdateFromData" label="UPDATE" description="UPDATE table" order="4">
<objectType name="org.jkiss.dbeaver.ui.controls.resultset.IResultSetController"/>
</generator>
<generator id="dataDeleteByUniqueKey" class="org.jkiss.dbeaver.ui.controls.resultset.generator.SQLGeneratorDeleteFromData" label="DELETE by Unique Key" description="DELETE from table" order="5">
<objectType name="org.jkiss.dbeaver.ui.controls.resultset.IResultSetController"/>
</generator>
</extension>
<extension point="org.eclipse.core.expressions.propertyTesters">
<propertyTester
class="org.jkiss.dbeaver.ui.controls.resultset.ResultSetPropertyTester"
......
......@@ -27,6 +27,7 @@ import org.jkiss.code.Nullable;
import org.jkiss.dbeaver.DBException;
import org.jkiss.dbeaver.model.DBPContextProvider;
import org.jkiss.dbeaver.model.DBPMessageType;
import org.jkiss.dbeaver.model.DBPObject;
import org.jkiss.dbeaver.model.data.DBDAttributeBinding;
import org.jkiss.dbeaver.model.data.DBDDataFilter;
import org.jkiss.dbeaver.model.data.DBDDataReceiver;
......@@ -42,7 +43,7 @@ import java.util.List;
* ResultSet controller.
* This interface is not supposed to be implemented by clients.
*/
public interface IResultSetController extends IDataController, DBPContextProvider {
public interface IResultSetController extends IDataController, DBPContextProvider, DBPObject {
String MENU_ID_EDIT = "edit";
String MENU_ID_VIEW = "view";
......
......@@ -14,7 +14,7 @@
* See the License for the specific language governing permissions and
* limitations under the License.
*/
package org.jkiss.dbeaver.ui.editors.sql.generator;
package org.jkiss.dbeaver.ui.controls.resultset.generator;
import org.jkiss.code.Nullable;
import org.jkiss.dbeaver.DBException;
......@@ -27,26 +27,33 @@ import org.jkiss.dbeaver.model.runtime.DBRProgressMonitor;
import org.jkiss.dbeaver.model.sql.SQLUtils;
import org.jkiss.dbeaver.model.sql.generator.BaseAnalysisRunner;
import org.jkiss.dbeaver.model.struct.DBSAttributeBase;
import org.jkiss.dbeaver.model.struct.DBSEntity;
import org.jkiss.dbeaver.ui.controls.resultset.IResultSetController;
import org.jkiss.dbeaver.ui.controls.resultset.ResultSetModel;
import org.jkiss.dbeaver.ui.controls.resultset.ResultSetRow;
import java.util.Collection;
import java.util.Collections;
import java.util.List;
public abstract class ResultSetAnalysisRunner extends BaseAnalysisRunner<ResultSetModel> {
public abstract class ResultSetAnalysisRunner extends BaseAnalysisRunner<IResultSetController> {
ResultSetAnalysisRunner(DBPDataSource dataSource, ResultSetModel model)
{
super(Collections.singletonList(model));
public IResultSetController getController() {
return objects.get(0);
}
public List<ResultSetRow> getSelectedRows() {
return getController().getSelection().getSelectedRows();
}
public DBSEntity getSingleEntity() {
return getController().getModel().getSingleSource();
}
protected abstract void generateSQL(DBRProgressMonitor monitor, StringBuilder sql, ResultSetModel object)
protected abstract void generateSQL(DBRProgressMonitor monitor, StringBuilder sql, IResultSetController object)
throws DBException;
protected Collection<? extends DBSAttributeBase> getAllAttributes(DBRProgressMonitor monitor, ResultSetModel object) {
return object.getVisibleAttributes();
protected Collection<? extends DBSAttributeBase> getAllAttributes(DBRProgressMonitor monitor, IResultSetController object) {
return object.getModel().getVisibleAttributes();
}
void appendValueCondition(IResultSetController rsv, StringBuilder sql, DBDAttributeBinding binding, ResultSetRow firstRow) {
......@@ -60,7 +67,7 @@ public abstract class ResultSetAnalysisRunner extends BaseAnalysisRunner<ResultS
}
}
protected List<DBDAttributeBinding> getKeyAttributes(DBRProgressMonitor monitor, ResultSetModel object) {
protected List<DBDAttributeBinding> getKeyAttributes(DBRProgressMonitor monitor, IResultSetController object) {
final DBDRowIdentifier rowIdentifier = getDefaultRowIdentifier(object);
if (rowIdentifier == null) {
return Collections.emptyList();
......@@ -69,8 +76,8 @@ public abstract class ResultSetAnalysisRunner extends BaseAnalysisRunner<ResultS
}
@Nullable
private DBDRowIdentifier getDefaultRowIdentifier(ResultSetModel object) {
for (DBDAttributeBinding attr : object.getAttributes()) {
private DBDRowIdentifier getDefaultRowIdentifier(IResultSetController object) {
for (DBDAttributeBinding attr : object.getModel().getAttributes()) {
DBDRowIdentifier rowIdentifier = attr.getRowIdentifier();
if (rowIdentifier != null) {
return rowIdentifier;
......
/*
* DBeaver - Universal Database Manager
* Copyright (C) 2010-2019 Serge Rider (serge@jkiss.org)
*
* 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 org.jkiss.dbeaver.ui.controls.resultset.generator;
import org.jkiss.dbeaver.model.data.DBDAttributeBinding;
import org.jkiss.dbeaver.model.runtime.DBRProgressMonitor;
import org.jkiss.dbeaver.ui.controls.resultset.IResultSetController;
import org.jkiss.dbeaver.ui.controls.resultset.ResultSetRow;
import java.util.Collection;
public class SQLGeneratorDeleteFromData extends ResultSetAnalysisRunner {
@Override
public void generateSQL(DBRProgressMonitor monitor, StringBuilder sql, IResultSetController object) {
for (ResultSetRow firstRow : getSelectedRows()) {
Collection<DBDAttributeBinding> keyAttributes = getKeyAttributes(monitor, object);
sql.append("DELETE FROM ").append(getEntityName(getSingleEntity()));
sql.append(getLineSeparator()).append("WHERE ");
boolean hasAttr = false;
for (DBDAttributeBinding binding : keyAttributes) {
if (hasAttr) sql.append(" AND ");
appendValueCondition(getController(), sql, binding, firstRow);
hasAttr = true;
}
sql.append(";\n");
}
}
}
......@@ -14,40 +14,26 @@
* See the License for the specific language governing permissions and
* limitations under the License.
*/
package org.jkiss.dbeaver.ui.editors.sql.generator;
package org.jkiss.dbeaver.ui.controls.resultset.generator;
import org.jkiss.dbeaver.model.DBPEvaluationContext;
import org.jkiss.dbeaver.model.DBUtils;
import org.jkiss.dbeaver.model.data.DBDAttributeBinding;
import org.jkiss.dbeaver.model.runtime.DBRProgressMonitor;
import org.jkiss.dbeaver.model.struct.DBSAttributeBase;
import org.jkiss.dbeaver.model.struct.DBSDataContainer;
import org.jkiss.dbeaver.model.struct.DBSEntity;
import org.jkiss.dbeaver.ui.controls.resultset.IResultSetController;
import org.jkiss.dbeaver.ui.controls.resultset.ResultSetModel;
import org.jkiss.dbeaver.ui.controls.resultset.ResultSetRow;
import java.util.Collection;
import java.util.List;
class SQLGeneratorInsertFromData extends ResultSetAnalysisRunner {
private final IResultSetController rsv;
private final List<ResultSetRow> selectedRows;
private final DBSEntity entity;
public SQLGeneratorInsertFromData(DBSDataContainer dataContainer, IResultSetController rsv, List<ResultSetRow> selectedRows, DBSEntity entity) {
super(dataContainer.getDataSource(), rsv.getModel());
this.rsv = rsv;
this.selectedRows = selectedRows;
this.entity = entity;
}
public class SQLGeneratorInsertFromData extends ResultSetAnalysisRunner {
@Override
public void generateSQL(DBRProgressMonitor monitor, StringBuilder sql, ResultSetModel object) {
for (ResultSetRow firstRow : selectedRows) {
public void generateSQL(DBRProgressMonitor monitor, StringBuilder sql, IResultSetController object) {
for (ResultSetRow firstRow : getSelectedRows()) {
Collection<? extends DBSAttributeBase> allAttributes = getAllAttributes(monitor, object);
sql.append("INSERT INTO ").append(getEntityName(entity));
sql.append("INSERT INTO ").append(getEntityName(getSingleEntity()));
sql.append(getLineSeparator()).append("(");
boolean hasAttr = false;
for (DBSAttributeBase attr : allAttributes) {
......@@ -65,11 +51,11 @@ class SQLGeneratorInsertFromData extends ResultSetAnalysisRunner {
continue;
}
if (hasAttr) sql.append(", ");
DBDAttributeBinding binding = rsv.getModel().getAttributeBinding(attr);
DBDAttributeBinding binding = getController().getModel().getAttributeBinding(attr);
if (binding == null) {
appendDefaultValue(sql, attr);
} else {
appendAttributeValue(rsv, sql, binding, firstRow);
appendAttributeValue(getController(), sql, binding, firstRow);
}
hasAttr = true;
}
......
......@@ -14,45 +14,42 @@
* See the License for the specific language governing permissions and
* limitations under the License.
*/
package org.jkiss.dbeaver.ui.editors.sql.generator;
package org.jkiss.dbeaver.ui.controls.resultset.generator;
import org.jkiss.dbeaver.model.DBPEvaluationContext;
import org.jkiss.dbeaver.model.DBUtils;
import org.jkiss.dbeaver.model.data.DBDAttributeBinding;
import org.jkiss.dbeaver.model.runtime.DBRProgressMonitor;
import org.jkiss.dbeaver.model.struct.DBSDataContainer;
import org.jkiss.dbeaver.model.struct.DBSEntity;
import org.jkiss.dbeaver.model.struct.DBSAttributeBase;
import org.jkiss.dbeaver.ui.controls.resultset.IResultSetController;
import org.jkiss.dbeaver.ui.controls.resultset.ResultSetModel;
import org.jkiss.dbeaver.ui.controls.resultset.ResultSetRow;
import java.util.Collection;
import java.util.List;
class SQLGeneratorDeleteFromData extends ResultSetAnalysisRunner {
private final IResultSetController rsv;
private final List<ResultSetRow> selectedRows;
private final DBSEntity entity;
public SQLGeneratorDeleteFromData(DBSDataContainer dataContainer, IResultSetController rsv, List<ResultSetRow> selectedRows, DBSEntity entity) {
super(dataContainer.getDataSource(), rsv.getModel());
this.rsv = rsv;
this.selectedRows = selectedRows;
this.entity = entity;
}
public class SQLGeneratorSelectFromData extends ResultSetAnalysisRunner {
@Override
public void generateSQL(DBRProgressMonitor monitor, StringBuilder sql, ResultSetModel object) {
for (ResultSetRow firstRow : selectedRows) {
public void generateSQL(DBRProgressMonitor monitor, StringBuilder sql, IResultSetController object) {
for (ResultSetRow firstRow : getSelectedRows()) {
Collection<DBDAttributeBinding> keyAttributes = getKeyAttributes(monitor, object);
sql.append("DELETE FROM ").append(getEntityName(entity));
sql.append(getLineSeparator()).append("WHERE ");
sql.append("SELECT ");
boolean hasAttr = false;
for (DBSAttributeBase attr : getAllAttributes(monitor, object)) {
if (hasAttr) sql.append(", ");
sql.append(DBUtils.getObjectFullName(attr, DBPEvaluationContext.DML));
hasAttr = true;
}
sql.append(getLineSeparator()).append("FROM ").append(getEntityName(getSingleEntity()));
sql.append(getLineSeparator()).append("WHERE ");
hasAttr = false;
for (DBDAttributeBinding binding : keyAttributes) {
if (hasAttr) sql.append(" AND ");
appendValueCondition(rsv, sql, binding, firstRow);
appendValueCondition(getController(), sql, binding, firstRow);
hasAttr = true;
}
sql.append(";\n");
}
}
}
......@@ -14,36 +14,23 @@
* See the License for the specific language governing permissions and
* limitations under the License.
*/
package org.jkiss.dbeaver.ui.editors.sql.generator;
package org.jkiss.dbeaver.ui.controls.resultset.generator;
import org.jkiss.dbeaver.model.DBPEvaluationContext;
import org.jkiss.dbeaver.model.DBUtils;
import org.jkiss.dbeaver.model.data.DBDAttributeBinding;
import org.jkiss.dbeaver.model.runtime.DBRProgressMonitor;
import org.jkiss.dbeaver.model.struct.DBSAttributeBase;
import org.jkiss.dbeaver.model.struct.DBSDataContainer;
import org.jkiss.dbeaver.model.struct.DBSEntity;
import org.jkiss.dbeaver.ui.controls.resultset.IResultSetController;
import org.jkiss.dbeaver.ui.controls.resultset.ResultSetModel;
import org.jkiss.dbeaver.ui.controls.resultset.ResultSetRow;
import java.util.Collection;
import java.util.List;
class SQLGeneratorSelectManyFromData extends ResultSetAnalysisRunner {
private final IResultSetController rsv;
private final DBSEntity entity;
private final List<ResultSetRow> selectedRows;
public SQLGeneratorSelectManyFromData(DBSDataContainer dataContainer, IResultSetController rsv, DBSEntity entity, List<ResultSetRow> selectedRows) {
super(dataContainer.getDataSource(), rsv.getModel());
this.rsv = rsv;
this.entity = entity;
this.selectedRows = selectedRows;
}
public class SQLGeneratorSelectManyFromData extends ResultSetAnalysisRunner {
@Override
public void generateSQL(DBRProgressMonitor monitor, StringBuilder sql, ResultSetModel object) {
public void generateSQL(DBRProgressMonitor monitor, StringBuilder sql, IResultSetController object) {
Collection<DBDAttributeBinding> keyAttributes = getKeyAttributes(monitor, object);
sql.append("SELECT ");
boolean hasAttr = false;
......@@ -52,7 +39,7 @@ class SQLGeneratorSelectManyFromData extends ResultSetAnalysisRunner {
sql.append(DBUtils.getObjectFullName(attr, DBPEvaluationContext.DML));
hasAttr = true;
}
sql.append(getLineSeparator()).append("FROM ").append(getEntityName(entity));
sql.append(getLineSeparator()).append("FROM ").append(getEntityName(getSingleEntity()));
sql.append(getLineSeparator()).append("WHERE ");
boolean multiKey = keyAttributes.size() > 1;
if (multiKey) sql.append("(");
......@@ -65,13 +52,14 @@ class SQLGeneratorSelectManyFromData extends ResultSetAnalysisRunner {
if (multiKey) sql.append(")");
sql.append(" IN (");
if (multiKey) sql.append("\n");
List<ResultSetRow> selectedRows = getSelectedRows();
for (int i = 0; i < selectedRows.size(); i++) {
ResultSetRow firstRow = selectedRows.get(i);
if (multiKey) sql.append("(");
hasAttr = false;
for (DBDAttributeBinding binding : keyAttributes) {
if (hasAttr) sql.append(",");
appendAttributeValue(rsv, sql, binding, firstRow);
appendAttributeValue(getController(), sql, binding, firstRow);
hasAttr = true;
}
if (multiKey) sql.append(")");
......
......@@ -14,7 +14,7 @@
* See the License for the specific language governing permissions and
* limitations under the License.
*/
package org.jkiss.dbeaver.ui.editors.sql.generator;
package org.jkiss.dbeaver.ui.controls.resultset.generator;
import org.jkiss.dbeaver.DBException;
import org.jkiss.dbeaver.model.DBPEvaluationContext;
......@@ -22,34 +22,20 @@ import org.jkiss.dbeaver.model.DBUtils;
import org.jkiss.dbeaver.model.data.DBDAttributeBinding;
import org.jkiss.dbeaver.model.runtime.DBRProgressMonitor;
import org.jkiss.dbeaver.model.struct.DBSAttributeBase;
import org.jkiss.dbeaver.model.struct.DBSDataContainer;
import org.jkiss.dbeaver.model.struct.DBSEntity;
import org.jkiss.dbeaver.ui.controls.resultset.IResultSetController;
import org.jkiss.dbeaver.ui.controls.resultset.ResultSetModel;
import org.jkiss.dbeaver.ui.controls.resultset.ResultSetRow;
import java.util.Collection;
import java.util.List;
class SQLGeneratorUpdateFromData extends ResultSetAnalysisRunner {
private final IResultSetController rsv;
private final List<ResultSetRow> selectedRows;
private final DBSEntity entity;
public SQLGeneratorUpdateFromData(DBSDataContainer dataContainer, IResultSetController rsv, List<ResultSetRow> selectedRows, DBSEntity entity) {
super(dataContainer.getDataSource(), rsv.getModel());
this.rsv = rsv;
this.selectedRows = selectedRows;
this.entity = entity;
}
public class SQLGeneratorUpdateFromData extends ResultSetAnalysisRunner {
@Override
public void generateSQL(DBRProgressMonitor monitor, StringBuilder sql, ResultSetModel object) throws DBException {
for (ResultSetRow firstRow : selectedRows) {
public void generateSQL(DBRProgressMonitor monitor, StringBuilder sql, IResultSetController object) throws DBException {
for (ResultSetRow firstRow : getSelectedRows()) {
Collection<DBDAttributeBinding> keyAttributes = getKeyAttributes(monitor, object);
Collection<? extends DBSAttributeBase> valueAttributes = getValueAttributes(monitor, object, keyAttributes);
sql.append("UPDATE ").append(getEntityName(entity));
sql.append("UPDATE ").append(getEntityName(getSingleEntity()));
sql.append(getLineSeparator()).append("SET ");
boolean hasAttr = false;
for (DBSAttributeBase attr : valueAttributes) {
......@@ -58,11 +44,11 @@ class SQLGeneratorUpdateFromData extends ResultSetAnalysisRunner {
}
if (hasAttr) sql.append(", ");
sql.append(DBUtils.getObjectFullName(attr, DBPEvaluationContext.DML)).append("=");
DBDAttributeBinding binding = rsv.getModel().getAttributeBinding(attr);
DBDAttributeBinding binding = getController().getModel().getAttributeBinding(attr);
if (binding == null) {
appendDefaultValue(sql, attr);
} else {
appendAttributeValue(rsv, sql, binding, firstRow);
appendAttributeValue(getController(), sql, binding, firstRow);
}
hasAttr = true;
......@@ -71,7 +57,7 @@ class SQLGeneratorUpdateFromData extends ResultSetAnalysisRunner {
hasAttr = false;
for (DBDAttributeBinding attr : keyAttributes) {
if (hasAttr) sql.append(" AND ");
appendValueCondition(rsv, sql, attr, firstRow);
appendValueCondition(getController(), sql, attr, firstRow);
hasAttr = true;
}
sql.append(";\n");
......
......@@ -32,27 +32,31 @@ import org.eclipse.ui.IWorkbenchPart;
import org.eclipse.ui.IWorkbenchPartSite;
import org.eclipse.ui.actions.CompoundContributionItem;
import org.jkiss.code.NotNull;
import org.jkiss.dbeaver.DBException;
import org.jkiss.dbeaver.Log;
import org.jkiss.dbeaver.model.DBPContextProvider;
import org.jkiss.dbeaver.model.DBPEvaluationContext;
import org.jkiss.dbeaver.model.DBPObject;
import org.jkiss.dbeaver.model.DBPScriptObject;
import org.jkiss.dbeaver.model.DBUtils;
import org.jkiss.dbeaver.model.data.DBDAttributeBinding;
import org.jkiss.dbeaver.model.exec.DBCExecutionContext;
import org.jkiss.dbeaver.model.runtime.DBRProgressMonitor;
import org.jkiss.dbeaver.model.sql.generator.*;
import org.jkiss.dbeaver.model.struct.DBSAttributeBase;
import org.jkiss.dbeaver.model.sql.generator.SQLGenerator;
import org.jkiss.dbeaver.model.sql.generator.SQLGeneratorProcedureCall;
import org.jkiss.dbeaver.model.sql.generator.SQLGeneratorSelect;
import org.jkiss.dbeaver.model.sql.registry.SQLGeneratorConfigurationRegistry;
import org.jkiss.dbeaver.model.sql.registry.SQLGeneratorDescriptor;
import org.jkiss.dbeaver.model.struct.DBSDataContainer;
import org.jkiss.dbeaver.model.struct.DBSEntity;
import org.jkiss.dbeaver.model.struct.DBSObject;
import org.jkiss.dbeaver.model.struct.DBSWrapper;
import org.jkiss.dbeaver.model.struct.rdb.DBSProcedure;
import org.jkiss.dbeaver.model.struct.rdb.DBSTable;
import org.jkiss.dbeaver.runtime.DBWorkbench;
import org.jkiss.dbeaver.ui.DBeaverIcons;
import org.jkiss.dbeaver.ui.UIIcon;
import org.jkiss.dbeaver.ui.UIUtils;
import org.jkiss.dbeaver.ui.controls.resultset.IResultSetController;
import org.jkiss.dbeaver.ui.controls.resultset.IResultSetSelection;
import org.jkiss.dbeaver.ui.controls.resultset.ResultSetModel;
import org.jkiss.dbeaver.ui.controls.resultset.ResultSetRow;
import org.jkiss.dbeaver.ui.editors.sql.dialogs.ViewSQLDialog;
import org.jkiss.dbeaver.ui.navigator.NavigatorUtils;
......@@ -60,7 +64,6 @@ import org.jkiss.dbeaver.utils.RuntimeUtils;
import org.jkiss.utils.CommonUtils;
import java.util.ArrayList;
import java.util.Collection;
import java.util.List;
public class GenerateSQLContributor extends CompoundContributionItem {
......@@ -71,8 +74,7 @@ public class GenerateSQLContributor extends CompoundContributionItem {
// Contributors
@Override
protected IContributionItem[] getContributionItems()
{
protected IContributionItem[] getContributionItems() {
IWorkbenchPart part = UIUtils.getActiveWorkbenchWindow().getActivePage().getActivePart();
IStructuredSelection structuredSelection = NavigatorUtils.getSelectionFromPart(part);
if (structuredSelection == null || structuredSelection.isEmpty()) {
......@@ -85,60 +87,30 @@ public class GenerateSQLContributor extends CompoundContributionItem {
makeResultSetContributions(menu, (IResultSetSelection) structuredSelection);
} else {
List<DBSEntity> entities = new ArrayList<>();
List<DBPScriptObject> scriptObjects = new ArrayList<>();
for (Object sel : structuredSelection.toArray()) {
final DBSObject object = RuntimeUtils.getObjectAdapter(sel, DBSObject.class);
if (object instanceof DBSEntity) {
entities.add((DBSEntity) object);
List<DBPObject> objects = new ArrayList<>();
for (Object obj : structuredSelection.toList()) {
if (obj instanceof DBSWrapper) {
objects.add(((DBSWrapper) obj).getObject());
} else if (obj instanceof DBPObject) {
objects.add((DBPObject) obj);
}
if (object instanceof DBPScriptObject) {
scriptObjects.add((DBPScriptObject) object);
}
}
if (!entities.isEmpty()) {
makeTableContributions(menu, entities);
}
if (!scriptObjects.isEmpty()) {
makeScriptContributions(menu, scriptObjects);
}
}
return menu.toArray(new IContributionItem[0]);
}
private void makeTableContributions(List<IContributionItem> menu, final List<DBSEntity> entities)
{
// Table
menu.add(makeAction("SELECT ", SELECT_GENERATOR(entities, true)));
menu.add(makeAction("INSERT ", INSERT_GENERATOR(entities)));
menu.add(makeAction("UPDATE ", UPDATE_GENERATOR(entities)));
menu.add(makeAction("DELETE ", DELETE_GENERATOR(entities)));
menu.add(makeAction("MERGE", MERGE_GENERATOR(entities)));
if (entities.size() > 1) {
menu.add(new Separator());
menu.add(makeAction("JOIN", JOIN_GENERATOR(entities)));
}
}
List<SQLGeneratorDescriptor> generators = SQLGeneratorConfigurationRegistry.getInstance().getApplicableGenerators(objects, structuredSelection);
int lastGrand = 0;
for (SQLGeneratorDescriptor gen : generators) {
int order = gen.getOrder();
if (order > 0 && order / 1000 > lastGrand) {
menu.add(new Separator());
}
lastGrand = order / 1000;
private void makeScriptContributions(List<IContributionItem> menu, final List<DBPScriptObject> scriptObjects)
{
if (menu.size() > 0) {
menu.add(new Separator());
}
List<DBSProcedure> procedures = new ArrayList<>();
for (DBPScriptObject so : scriptObjects) {
if (so instanceof DBSProcedure) {
procedures.add((DBSProcedure) so);
menu.add(makeAction(gen.getLabel(), gen, objects));
}
}
if (!procedures.isEmpty()) {
menu.add(makeAction("CALL", CALL_GENERATOR(procedures)));
}
menu.add(makeAction("DDL", new SQLGeneratorDDL(scriptObjects)));
return menu.toArray(new IContributionItem[0]);
}
private void makeResultSetContributions(List<IContributionItem> menu, IResultSetSelection rss)
{
private void makeResultSetContributions(List<IContributionItem> menu, IResultSetSelection rss) {
final IResultSetController rsv = rss.getController();
DBSDataContainer dataContainer = rsv.getDataContainer();
final List<DBDAttributeBinding> visibleAttributes = rsv.getModel().getVisibleAttributes();
......@@ -147,15 +119,15 @@ public class GenerateSQLContributor extends CompoundContributionItem {
final List<ResultSetRow> selectedRows = new ArrayList<>(rss.getSelectedRows());
if (!CommonUtils.isEmpty(selectedRows)) {
menu.add(makeAction("SELECT .. WHERE .. =", new SQLGeneratorSelectFromData(dataContainer, rsv, selectedRows, entity)));
if (selectedRows.size() > 1) {
menu.add(makeAction("SELECT .. WHERE .. IN", new SQLGeneratorSelectManyFromData(dataContainer, rsv, entity, selectedRows)));
List<IResultSetController> objects = new ArrayList<>();
objects.add(rsv);
List<SQLGeneratorDescriptor> generators = SQLGeneratorConfigurationRegistry.getInstance().getApplicableGenerators(objects, rsv);
for (SQLGeneratorDescriptor gen : generators) {
if (gen.isMultiObject() && selectedRows.size() < 2) {
continue;
}
menu.add(makeAction(gen.getLabel(), gen, objects));
}
menu.add(makeAction("INSERT", new SQLGeneratorInsertFromData(dataContainer, rsv, selectedRows, entity)));
menu.add(makeAction("UPDATE", new SQLGeneratorUpdateFromData(dataContainer, rsv, selectedRows, entity)));
menu.add(makeAction("DELETE by Unique Key", new SQLGeneratorDeleteFromData(dataContainer, rsv, selectedRows, entity)));
}
} else {
//if (dataContainer != null && !visibleAttributes.isEmpty() && entity != null)
......@@ -174,13 +146,11 @@ public class GenerateSQLContributor extends CompoundContributionItem {
return object instanceof DBSTable || object instanceof DBPScriptObject;
}
private static ContributionItem makeAction(String text, final SQLGenerator<?> sqlGenerator)
{
private static ContributionItem makeAction(String text, SQLGeneratorDescriptor sqlGenerator, List<?> objects) {
return new ActionContributionItem(
new Action(text, DBeaverIcons.getImageDescriptor(UIIcon.SQL_TEXT)) {
@Override
public void run()
{
public void run() {
IWorkbenchPage activePage = UIUtils.getActiveWorkbenchWindow().getActivePage();
IEditorPart activeEditor = activePage.getActiveEditor();
......@@ -200,14 +170,21 @@ public class GenerateSQLContributor extends CompoundContributionItem {
}
if (executionContext != null) {
SQLGenerator<?> generator;
try {
generator = sqlGenerator.createGenerator(objects);
} catch (DBException e) {
DBWorkbench.getPlatformUI().showError("Generator create", "Can't create SQL generator '" + sqlGenerator.getId() + "'", e);
return;
}
ViewSQLDialog dialog = new GenerateSQLDialog(
activePage.getActivePart().getSite(),
executionContext,
sqlGenerator);
generator);
dialog.open();
}
}
});
});
}
private static class GenerateSQLDialog extends ViewSQLDialog {
......@@ -230,7 +207,7 @@ public class GenerateSQLContributor extends CompoundContributionItem {
getDialogBoundsSettings().getBoolean(PROP_USE_FQ_NAMES));
sqlGenerator.setCompactSQL(
getDialogBoundsSettings().get(PROP_USE_COMPACT_SQL) != null &&
getDialogBoundsSettings().getBoolean(PROP_USE_COMPACT_SQL));
getDialogBoundsSettings().getBoolean(PROP_USE_COMPACT_SQL));
UIUtils.runInUI(sqlGenerator);
Object sql = sqlGenerator.getResult();
if (sql != null) {
......@@ -280,75 +257,17 @@ public class GenerateSQLContributor extends CompoundContributionItem {
@NotNull
public static SQLGenerator<DBSEntity> SELECT_GENERATOR(final List<DBSEntity> entities, final boolean columnList) {
return new SQLGeneratorSelect(entities, columnList);
}
@NotNull
private SQLGenerator<DBSEntity> DELETE_GENERATOR(final List<DBSEntity> entities) {
return new SQLGeneratorDelete(entities);
}
@NotNull
private static SQLGenerator<DBSEntity> INSERT_GENERATOR(final List<DBSEntity> entities) {
return new SQLGeneratorInsert(entities);
}
@NotNull
private static SQLGenerator<DBSEntity> UPDATE_GENERATOR(final List<DBSEntity> entities) {
return new SQLGeneratorUpdate(entities);
}
@NotNull
private static SQLGenerator<DBSEntity> MERGE_GENERATOR(final List<DBSEntity> entities) {
return new SQLGeneratorMerge(entities);
}
@NotNull
private static SQLGenerator<DBSEntity> JOIN_GENERATOR(final List<DBSEntity> entities) {
return new SQLGeneratorJoin(entities);
SQLGeneratorSelect generatorSelect = new SQLGeneratorSelect();
generatorSelect.initGenerator(entities);
generatorSelect.setColumnList(columnList);
return generatorSelect;
}
@NotNull
public static SQLGenerator<DBSProcedure> CALL_GENERATOR(final List<DBSProcedure> entities) {
return new SQLGeneratorProcedureCall(entities);
}
private static class SQLGeneratorSelectFromData extends ResultSetAnalysisRunner {
private final IResultSetController rsv;
private final List<ResultSetRow> selectedRows;
private final DBSEntity entity;
public SQLGeneratorSelectFromData(DBSDataContainer dataContainer, IResultSetController rsv, List<ResultSetRow> selectedRows, DBSEntity entity) {
super(dataContainer.getDataSource(), rsv.getModel());
this.rsv = rsv;
this.selectedRows = selectedRows;
this.entity = entity;
}
@Override
public void generateSQL(DBRProgressMonitor monitor, StringBuilder sql, ResultSetModel object) {
for (ResultSetRow firstRow : selectedRows) {
Collection<DBDAttributeBinding> keyAttributes = getKeyAttributes(monitor, object);
sql.append("SELECT ");
boolean hasAttr = false;
for (DBSAttributeBase attr : getAllAttributes(monitor, object)) {
if (hasAttr) sql.append(", ");
sql.append(DBUtils.getObjectFullName(attr, DBPEvaluationContext.DML));
hasAttr = true;
}
sql.append(getLineSeparator()).append("FROM ").append(getEntityName(entity));
sql.append(getLineSeparator()).append("WHERE ");
hasAttr = false;
for (DBDAttributeBinding binding : keyAttributes) {
if (hasAttr) sql.append(" AND ");
appendValueCondition(rsv, sql, binding, firstRow);
hasAttr = true;
}
sql.append(";\n");
}
}
SQLGeneratorProcedureCall procedureCall = new SQLGeneratorProcedureCall();
procedureCall.initGenerator(entities);
return procedureCall;
}
}
Markdown is supported
0% .
You are about to add 0 people to the discussion. Proceed with caution.
先完成此消息的编辑!
想要评论请 注册