diff --git a/plugins/org.jkiss.dbeaver.ext.oceanbase/plugin.xml b/plugins/org.jkiss.dbeaver.ext.oceanbase/plugin.xml
index 9a24cc884ac68fdc0182222bffc2518eea476b24..4201ce4da02f2fbe7876cad520ade9801bfb6780 100644
--- a/plugins/org.jkiss.dbeaver.ext.oceanbase/plugin.xml
+++ b/plugins/org.jkiss.dbeaver.ext.oceanbase/plugin.xml
@@ -16,7 +16,7 @@
icon="icons/ob_icon.png"
label="OceanBase data source"
path="oceanbase">
-
+
@@ -68,6 +68,12 @@
+
+
+
+
+
+
@@ -152,7 +158,10 @@
-
+
@@ -193,4 +202,8 @@
uiClass="org.jkiss.dbeaver.ui.dialogs.connection.DatabaseNativeAuthModelConfigurator"/>
+
+
+
+
diff --git a/plugins/org.jkiss.dbeaver.ext.oceanbase/src/org/jkiss/dbeaver/ext/oceanbase/mysql/model/OceanbaseMySQLCatalog.java b/plugins/org.jkiss.dbeaver.ext.oceanbase/src/org/jkiss/dbeaver/ext/oceanbase/mysql/model/OceanbaseMySQLCatalog.java
new file mode 100644
index 0000000000000000000000000000000000000000..65395310018204d23933a80e3c45f726f8e1b298
--- /dev/null
+++ b/plugins/org.jkiss.dbeaver.ext.oceanbase/src/org/jkiss/dbeaver/ext/oceanbase/mysql/model/OceanbaseMySQLCatalog.java
@@ -0,0 +1,183 @@
+package org.jkiss.dbeaver.ext.oceanbase.mysql.model;
+
+import java.sql.DatabaseMetaData;
+import java.sql.ResultSet;
+import java.sql.SQLException;
+import java.util.ArrayList;
+import java.util.Collection;
+import java.util.Collections;
+import java.util.List;
+
+import org.jkiss.code.NotNull;
+import org.jkiss.dbeaver.DBException;
+import org.jkiss.dbeaver.ext.mysql.MySQLConstants;
+import org.jkiss.dbeaver.ext.mysql.model.MySQLCatalog;
+import org.jkiss.dbeaver.ext.mysql.model.MySQLDataSource;
+import org.jkiss.dbeaver.ext.mysql.model.MySQLProcedure;
+import org.jkiss.dbeaver.ext.mysql.model.MySQLProcedureParameter;
+import org.jkiss.dbeaver.model.exec.jdbc.JDBCPreparedStatement;
+import org.jkiss.dbeaver.model.exec.jdbc.JDBCResultSet;
+import org.jkiss.dbeaver.model.exec.jdbc.JDBCSession;
+import org.jkiss.dbeaver.model.exec.jdbc.JDBCStatement;
+import org.jkiss.dbeaver.model.impl.jdbc.JDBCConstants;
+import org.jkiss.dbeaver.model.impl.jdbc.JDBCUtils;
+import org.jkiss.dbeaver.model.impl.jdbc.cache.JDBCStructLookupCache;
+import org.jkiss.dbeaver.model.runtime.DBRProgressMonitor;
+import org.jkiss.dbeaver.model.struct.DBSObject;
+import org.jkiss.dbeaver.model.struct.rdb.DBSProcedureParameterKind;
+import org.jkiss.dbeaver.model.struct.rdb.DBSProcedureType;
+import org.jkiss.utils.CommonUtils;
+
+public class OceanbaseMySQLCatalog extends MySQLCatalog{
+ private final OceanbaseMySQLDataSource dataSource;
+ final OceanbaseProceduresCache oceanbaseProceduresCache = new OceanbaseProceduresCache();
+
+ static class OceanbaseProceduresCache extends JDBCStructLookupCache {
+
+ public OceanbaseProceduresCache() {
+ super(JDBCConstants.PROCEDURE_NAME);
+ }
+
+ @Override
+ public JDBCStatement prepareLookupStatement(JDBCSession session, OceanbaseMySQLCatalog owner, OceanbaseMySQLProcedure object,
+ String objectName) throws SQLException {
+ JDBCPreparedStatement dbStat = session.prepareStatement(
+ "SELECT * FROM " + MySQLConstants.META_TABLE_ROUTINES +
+ "\nWHERE " + MySQLConstants.COL_ROUTINE_SCHEMA + "=?" +
+ (object == null && objectName == null ? "" : " AND " + MySQLConstants.COL_ROUTINE_NAME + "=?") +
+ " AND ROUTINE_TYPE" + (object == null ? " IN ('PROCEDURE','FUNCTION')" : "=?") +
+ "\nORDER BY " + MySQLConstants.COL_ROUTINE_NAME
+ );
+ dbStat.setString(1, owner.getName());
+ if (object != null || objectName != null) {
+ dbStat.setString(2, object != null ? object.getName() : objectName);
+ if (object != null) {
+ dbStat.setString(3, String.valueOf(object.getProcedureType()));
+ }
+ }
+ return dbStat;
+ }
+
+ @Override
+ protected JDBCStatement prepareChildrenStatement(JDBCSession session, OceanbaseMySQLCatalog owner,
+ OceanbaseMySQLProcedure procedure) throws SQLException {
+ if(procedure.getProcedureType().equals(DBSProcedureType.PROCEDURE)) {
+ return session.getMetaData().getProcedureColumns(
+ owner.getName(),
+ null,
+ procedure == null ? null : JDBCUtils.escapeWildCards(session, procedure.getName()),
+ "%").getSourceStatement();
+ }
+ else {
+ String queryFunctionString = "select * from mysql.proc where db='%s' and type='FUNCTION' and name='%s'";
+ return session.prepareStatement(String.format(queryFunctionString, owner.getName(), procedure.getName()));
+ }
+ }
+
+ @Override
+ protected MySQLProcedureParameter fetchChild(JDBCSession session, OceanbaseMySQLCatalog owner, OceanbaseMySQLProcedure parent,
+ JDBCResultSet dbResult) throws SQLException, DBException {
+ if(parent.getProcedureType().equals(DBSProcedureType.PROCEDURE)) {
+ String columnName = JDBCUtils.safeGetString(dbResult, JDBCConstants.COLUMN_NAME);
+ int columnTypeNum = JDBCUtils.safeGetInt(dbResult, JDBCConstants.COLUMN_TYPE);
+ int valueType = JDBCUtils.safeGetInt(dbResult, JDBCConstants.DATA_TYPE);
+ String typeName = JDBCUtils.safeGetString(dbResult, JDBCConstants.TYPE_NAME);
+ int position = JDBCUtils.safeGetInt(dbResult, JDBCConstants.ORDINAL_POSITION);
+ long columnSize = JDBCUtils.safeGetLong(dbResult, JDBCConstants.LENGTH);
+ boolean notNull = JDBCUtils.safeGetInt(dbResult, JDBCConstants.NULLABLE) == DatabaseMetaData.procedureNoNulls;
+ int scale = JDBCUtils.safeGetInt(dbResult, JDBCConstants.SCALE);
+ int precision = JDBCUtils.safeGetInt(dbResult, JDBCConstants.PRECISION);
+ DBSProcedureParameterKind parameterType;
+ switch (columnTypeNum) {
+ case DatabaseMetaData.procedureColumnIn: parameterType = DBSProcedureParameterKind.IN; break;
+ case DatabaseMetaData.procedureColumnInOut: parameterType = DBSProcedureParameterKind.INOUT; break;
+ case DatabaseMetaData.procedureColumnOut: parameterType = DBSProcedureParameterKind.OUT; break;
+ case DatabaseMetaData.procedureColumnReturn: parameterType = DBSProcedureParameterKind.RETURN; break;
+ case DatabaseMetaData.procedureColumnResult: parameterType = DBSProcedureParameterKind.RESULTSET; break;
+ default: parameterType = DBSProcedureParameterKind.UNKNOWN; break;
+ }
+ if (CommonUtils.isEmpty(columnName) && parameterType == DBSProcedureParameterKind.RETURN) {
+ columnName = "RETURN";
+ }
+ return new MySQLProcedureParameter(
+ parent,
+ columnName,
+ typeName,
+ valueType,
+ position,
+ columnSize,
+ scale, precision, notNull,
+ parameterType);
+ } else {
+ String[] paramList = JDBCUtils.safeGetString(dbResult, "returns").split("\\(");
+ int columnSize = Integer.parseInt(paramList[1].split("\\)")[0]);
+
+ return new MySQLProcedureParameter(
+ parent,
+ "RETURN",
+ paramList[0],
+ STRUCT_ATTRIBUTES,
+ 0,
+ columnSize,
+ null,
+ null,
+ true,
+ null);
+ }
+ }
+
+ @Override
+ protected OceanbaseMySQLProcedure fetchObject(JDBCSession session, OceanbaseMySQLCatalog owner, JDBCResultSet resultSet)
+ throws SQLException, DBException {
+ return new OceanbaseMySQLProcedure(owner, resultSet);
+ }
+
+ }
+
+ public OceanbaseMySQLCatalog(OceanbaseMySQLDataSource dataSource, ResultSet dbResult) {
+ super(dataSource, dbResult);
+ this.dataSource = dataSource;
+ }
+
+ public OceanbaseProceduresCache getOceanbaseProceduresCache() {
+ return this.oceanbaseProceduresCache;
+ }
+
+ @Override
+ public Collection getProcedures(DBRProgressMonitor monitor) throws DBException {
+ if(!getDataSource().supportsInformationSchema()) {
+ return Collections.emptyList();
+ }
+ List objects = new ArrayList<>();
+ for(OceanbaseMySQLProcedure oceanbaseMySQLProcedure : oceanbaseProceduresCache.getAllObjects(monitor, this)) {
+ objects.add(oceanbaseMySQLProcedure);
+ }
+ return objects;
+ }
+
+ @Override
+ public MySQLProcedure getProcedure(DBRProgressMonitor monitor, String procName)
+ throws DBException
+ {
+ return oceanbaseProceduresCache.getObject(monitor, this, procName);
+ }
+
+ @Override
+ public synchronized DBSObject refreshObject(@NotNull DBRProgressMonitor monitor)
+ throws DBException
+ {
+ super.refreshObject(monitor);
+ oceanbaseProceduresCache.clearCache();
+ return this;
+ }
+
+ @NotNull
+ @Override
+ public MySQLDataSource getDataSource()
+ {
+ return (OceanbaseMySQLDataSource)dataSource;
+ }
+
+
+
+}
diff --git a/plugins/org.jkiss.dbeaver.ext.oceanbase/src/org/jkiss/dbeaver/ext/oceanbase/mysql/model/OceanbaseMySQLDataSource.java b/plugins/org.jkiss.dbeaver.ext.oceanbase/src/org/jkiss/dbeaver/ext/oceanbase/mysql/model/OceanbaseMySQLDataSource.java
index eedcac6da249ee767a9e993365a4715dae8fb802..67d6118c25885be25162b5675e7fa3528a2e9c29 100644
--- a/plugins/org.jkiss.dbeaver.ext.oceanbase/src/org/jkiss/dbeaver/ext/oceanbase/mysql/model/OceanbaseMySQLDataSource.java
+++ b/plugins/org.jkiss.dbeaver.ext.oceanbase/src/org/jkiss/dbeaver/ext/oceanbase/mysql/model/OceanbaseMySQLDataSource.java
@@ -16,32 +16,50 @@
*/
package org.jkiss.dbeaver.ext.oceanbase.mysql.model;
+import java.sql.SQLException;
+import java.util.ArrayList;
import java.util.Collection;
+import java.util.List;
import org.jkiss.code.NotNull;
+import org.jkiss.code.Nullable;
import org.jkiss.dbeaver.DBException;
+import org.jkiss.dbeaver.ext.mysql.MySQLConstants;
+import org.jkiss.dbeaver.ext.mysql.model.MySQLCatalog;
import org.jkiss.dbeaver.ext.mysql.model.MySQLDataSource;
import org.jkiss.dbeaver.ext.mysql.model.MySQLEngine;
import org.jkiss.dbeaver.ext.mysql.model.MySQLPrivilege;
+import org.jkiss.dbeaver.ext.mysql.model.MySQLTable;
import org.jkiss.dbeaver.ext.oceanbase.model.plan.OceanbasePlanAnalyzer;
import org.jkiss.dbeaver.model.DBPDataSourceContainer;
import org.jkiss.dbeaver.model.DBUtils;
import org.jkiss.dbeaver.model.data.DBDValueHandlerProvider;
+import org.jkiss.dbeaver.model.exec.jdbc.JDBCPreparedStatement;
+import org.jkiss.dbeaver.model.exec.jdbc.JDBCResultSet;
+import org.jkiss.dbeaver.model.exec.jdbc.JDBCSession;
+import org.jkiss.dbeaver.model.exec.jdbc.JDBCStatement;
import org.jkiss.dbeaver.model.exec.plan.DBCQueryPlanner;
+import org.jkiss.dbeaver.model.impl.jdbc.JDBCUtils;
import org.jkiss.dbeaver.model.impl.jdbc.cache.JDBCBasicDataTypeCache;
+import org.jkiss.dbeaver.model.impl.jdbc.cache.JDBCObjectCache;
import org.jkiss.dbeaver.model.impl.jdbc.data.handlers.JDBCStandardValueHandlerProvider;
import org.jkiss.dbeaver.model.impl.jdbc.struct.JDBCDataType;
import org.jkiss.dbeaver.model.runtime.DBRProgressMonitor;
import org.jkiss.dbeaver.model.struct.DBSDataType;
+import org.jkiss.dbeaver.model.struct.DBSObjectFilter;
+import org.jkiss.utils.CommonUtils;
public class OceanbaseMySQLDataSource extends MySQLDataSource {
private final JDBCBasicDataTypeCache dataTypeCache;
+ private final String tenantType;
+ private final OceanbaseCatalogCache oceanbaseCatalogCache = new OceanbaseCatalogCache();
public OceanbaseMySQLDataSource(DBRProgressMonitor monitor, DBPDataSourceContainer container)
throws DBException
{
super(monitor, container);
dataTypeCache = new JDBCBasicDataTypeCache<>(this);
+ tenantType = container.getConnectionConfiguration().getProviderProperty("tenantType");
}
@Override
@@ -49,6 +67,8 @@ public class OceanbaseMySQLDataSource extends MySQLDataSource {
throws DBException {
super.initialize(monitor);
dataTypeCache.getAllObjects(monitor, this);
+ // Read catalogs
+ oceanbaseCatalogCache.getAllObjects(monitor, this);
}
@Override
@@ -97,4 +117,85 @@ public class OceanbaseMySQLDataSource extends MySQLDataSource {
public DBSDataType getLocalDataType(int typeID) {
return dataTypeCache.getCachedObject(typeID);
}
+
+ public boolean isMySQLMode () {
+ return tenantType.equals("MySQL");
+ }
+
+ MySQLTable findTable(DBRProgressMonitor monitor, String catalogName, String tableName)throws DBException {
+ if (CommonUtils.isEmpty(catalogName)) {
+ return null;
+ }
+ OceanbaseMySQLCatalog catalog = (OceanbaseMySQLCatalog)getCatalog(catalogName);
+ if (catalog == null) {
+ return null;
+ }
+ return catalog.getTable(monitor, tableName);
+ }
+
+ @Override
+ public Collection extends MySQLCatalog> getChildren(@NotNull DBRProgressMonitor monitor)
+ throws DBException {
+ return getCatalogs();
+ }
+
+ @Override
+ public MySQLCatalog getChild(@NotNull DBRProgressMonitor monitor, @NotNull String childName)
+ throws DBException {
+ return getCatalog(childName);
+ }
+
+ @NotNull
+ @Override
+ public Class extends MySQLCatalog> getPrimaryChildType(@Nullable DBRProgressMonitor monitor)
+ throws DBException {
+ return OceanbaseMySQLCatalog.class;
+ }
+
+ public OceanbaseCatalogCache getOceanbaseCatalogCache() {
+ return oceanbaseCatalogCache;
+ }
+
+ @Override
+ public MySQLCatalog getCatalog(String name) {
+ return oceanbaseCatalogCache.getCachedObject(name);
+ }
+
+ @Override
+ public Collection getCatalogs() {
+ List catalogs = new ArrayList<>();
+ for (OceanbaseMySQLCatalog oceanbaseMySQLCatalog : oceanbaseCatalogCache.getCachedObjects()) {
+ catalogs.add(oceanbaseMySQLCatalog);
+ }
+ return catalogs;
+ }
+
+ static class OceanbaseCatalogCache extends JDBCObjectCache {
+ @NotNull
+ @Override
+ protected JDBCStatement prepareObjectsStatement(@NotNull JDBCSession session, @NotNull OceanbaseMySQLDataSource owner) throws SQLException {
+ StringBuilder catalogQuery = new StringBuilder("show databases");
+ DBSObjectFilter catalogFilters = owner.getContainer().getObjectFilter(MySQLCatalog.class, null, false);
+ if (catalogFilters != null) {
+ JDBCUtils.appendFilterClause(catalogQuery, catalogFilters, MySQLConstants.COL_DATABASE_NAME, true);
+ }
+ JDBCPreparedStatement dbStat = session.prepareStatement(catalogQuery.toString());
+ if (catalogFilters != null) {
+ JDBCUtils.setFilterParameters(dbStat, 1, catalogFilters);
+ }
+ return dbStat;
+ }
+
+ @Override
+ protected OceanbaseMySQLCatalog fetchObject(@NotNull JDBCSession session, @NotNull OceanbaseMySQLDataSource owner, @NotNull JDBCResultSet resultSet) throws SQLException, DBException {
+ return new OceanbaseMySQLCatalog(owner, resultSet);
+ }
+
+ }
+
+ @Override
+ public boolean supportsInformationSchema() {
+ return true;
+ }
+
}
diff --git a/plugins/org.jkiss.dbeaver.ext.oceanbase/src/org/jkiss/dbeaver/ext/oceanbase/mysql/model/OceanbaseMySQLDatabaseManager.java b/plugins/org.jkiss.dbeaver.ext.oceanbase/src/org/jkiss/dbeaver/ext/oceanbase/mysql/model/OceanbaseMySQLDatabaseManager.java
new file mode 100644
index 0000000000000000000000000000000000000000..83b91b5b8a3cf97f0d52e04fb5f0d91b3a05f399
--- /dev/null
+++ b/plugins/org.jkiss.dbeaver.ext.oceanbase/src/org/jkiss/dbeaver/ext/oceanbase/mysql/model/OceanbaseMySQLDatabaseManager.java
@@ -0,0 +1,73 @@
+package org.jkiss.dbeaver.ext.oceanbase.mysql.model;
+
+import java.util.List;
+import java.util.Map;
+
+import org.jkiss.dbeaver.DBException;
+import org.jkiss.dbeaver.model.DBPDataSource;
+import org.jkiss.dbeaver.model.edit.DBECommandContext;
+import org.jkiss.dbeaver.model.edit.DBEObjectRenamer;
+import org.jkiss.dbeaver.model.edit.DBEPersistAction;
+import org.jkiss.dbeaver.model.exec.DBCExecutionContext;
+import org.jkiss.dbeaver.model.impl.edit.SQLDatabasePersistAction;
+import org.jkiss.dbeaver.model.impl.sql.edit.SQLObjectEditor;
+import org.jkiss.dbeaver.model.runtime.DBRProgressMonitor;
+import org.jkiss.dbeaver.model.struct.DBSObject;
+import org.jkiss.dbeaver.model.struct.cache.DBSObjectCache;
+
+public class OceanbaseMySQLDatabaseManager extends SQLObjectEditor implements DBEObjectRenamer{
+
+ @Override
+ public long getMakerOptions(DBPDataSource dataSource) {
+ return FEATURE_SAVE_IMMEDIATELY;
+ }
+
+ @Override
+ public DBSObjectCache extends DBSObject, OceanbaseMySQLCatalog> getObjectsCache(OceanbaseMySQLCatalog object) {
+ return ((OceanbaseMySQLDataSource)object.getDataSource()).getOceanbaseCatalogCache();
+ }
+
+ @Override
+ public void renameObject(DBECommandContext commandContext, OceanbaseMySQLCatalog object,
+ Map options, String newName) throws DBException {
+ throw new DBException("Direct database rename is not yet implemented in MySQL. You should use export/import functions for that.");
+ }
+
+ @Override
+ protected OceanbaseMySQLCatalog createDatabaseObject(DBRProgressMonitor monitor, DBECommandContext context,
+ Object container, Object copyFrom, Map options) throws DBException {
+ System.out.println("11111");
+ return new OceanbaseMySQLCatalog((OceanbaseMySQLDataSource) container, null);
+ }
+
+ @Override
+ protected void addObjectCreateActions(DBRProgressMonitor monitor, DBCExecutionContext executionContext,
+ List actions,
+ SQLObjectEditor.ObjectCreateCommand command,
+ Map options) throws DBException {
+ final OceanbaseMySQLCatalog catalog = command.getObject();
+ final StringBuilder script = new StringBuilder("CREATE SCHEMA `" + catalog.getName() + "`");
+ appendDatabaseModifiers(catalog, script);
+ actions.add(
+ new SQLDatabasePersistAction("Create schema", script.toString()) //$NON-NLS-2$
+ );
+ }
+
+ @Override
+ protected void addObjectDeleteActions(DBRProgressMonitor monitor, DBCExecutionContext executionContext,
+ List actions,
+ SQLObjectEditor.ObjectDeleteCommand command,
+ Map options) throws DBException {
+ actions.add(new SQLDatabasePersistAction("Drop schema", "DROP SCHEMA `" + command.getObject().getName() + "`"));
+ }
+
+ private void appendDatabaseModifiers(OceanbaseMySQLCatalog catalog, StringBuilder script) {
+ if (catalog.getAdditionalInfo().getDefaultCharset() != null) {
+ script.append("\nDEFAULT CHARACTER SET ").append(catalog.getAdditionalInfo().getDefaultCharset().getName());
+ }
+ if (catalog.getAdditionalInfo().getDefaultCollation() != null) {
+ script.append("\nDEFAULT COLLATE ").append(catalog.getAdditionalInfo().getDefaultCollation().getName());
+ }
+ }
+
+}
diff --git a/plugins/org.jkiss.dbeaver.ext.oceanbase/src/org/jkiss/dbeaver/ext/oceanbase/mysql/model/OceanbaseMySQLProcedure.java b/plugins/org.jkiss.dbeaver.ext.oceanbase/src/org/jkiss/dbeaver/ext/oceanbase/mysql/model/OceanbaseMySQLProcedure.java
new file mode 100644
index 0000000000000000000000000000000000000000..f23cf79e40801ea5e9127961c5ed28ded1eda9d3
--- /dev/null
+++ b/plugins/org.jkiss.dbeaver.ext.oceanbase/src/org/jkiss/dbeaver/ext/oceanbase/mysql/model/OceanbaseMySQLProcedure.java
@@ -0,0 +1,36 @@
+package org.jkiss.dbeaver.ext.oceanbase.mysql.model;
+
+import java.sql.ResultSet;
+import java.util.Collection;
+import org.jkiss.code.NotNull;
+import org.jkiss.dbeaver.DBException;
+import org.jkiss.dbeaver.ext.mysql.model.MySQLCatalog;
+import org.jkiss.dbeaver.ext.mysql.model.MySQLProcedure;
+import org.jkiss.dbeaver.ext.mysql.model.MySQLProcedureParameter;
+import org.jkiss.dbeaver.model.runtime.DBRProgressMonitor;
+import org.jkiss.dbeaver.model.struct.DBSObject;
+
+public class OceanbaseMySQLProcedure extends MySQLProcedure{
+ private OceanbaseMySQLCatalog container = (OceanbaseMySQLCatalog)getContainer();
+
+ public OceanbaseMySQLProcedure(MySQLCatalog catalog) {
+ super(catalog);
+ }
+
+ public OceanbaseMySQLProcedure(MySQLCatalog catalog, ResultSet dbResult) {
+ super(catalog, dbResult);
+ }
+
+ @Override
+ public Collection getParameters(DBRProgressMonitor monitor)
+ throws DBException
+ {
+ return container.oceanbaseProceduresCache.getChildren(monitor, container, this);
+ }
+
+ @Override
+ public DBSObject refreshObject(@NotNull DBRProgressMonitor monitor) throws DBException {
+ return container.oceanbaseProceduresCache.refreshObject(monitor, container, this);
+ }
+
+}