diff --git a/plugins/org.jkiss.dbeaver.ext.mysql/OSGI-INF/l10n/bundle.properties b/plugins/org.jkiss.dbeaver.ext.mysql/OSGI-INF/l10n/bundle.properties
index 9cccc183a69207887290c9308900a2486e9e4d87..b6a35361e9e7f0ad376c39bb894fa819ce1ae40f 100644
--- a/plugins/org.jkiss.dbeaver.ext.mysql/OSGI-INF/l10n/bundle.properties
+++ b/plugins/org.jkiss.dbeaver.ext.mysql/OSGI-INF/l10n/bundle.properties
@@ -48,6 +48,9 @@ tree.charset.node.name=Charset
tree.collation.node.name=Collation
tree.events.node.name=Events
tree.event.node.name=Event
+tree.packages.node.name=Packages
+tree.packages.node.description=MariaDB Packages (Oracle mode)
+tree.package.node.name=Package
manager.catalog.name=Catalog manager
@@ -55,6 +58,9 @@ editor.general.name=General
editor.schema_privileges.name=Schema Privileges
editor.session_manager.name=Session Manager
editor.source.name=Source
+editor.package.body.name=Body source
+editor.package.body.description=Package body source
+
meta.org.jkiss.dbeaver.ext.mysql.model.MySQLCatalog.name.name=Schema Name
meta.org.jkiss.dbeaver.ext.mysql.model.MySQLCatalog.defaultCharset.name=Default Charset
meta.org.jkiss.dbeaver.ext.mysql.model.MySQLCatalog.defaultCollation.name=Default Collation
@@ -194,6 +200,10 @@ meta.org.jkiss.dbeaver.ext.mysql.model.session.MySQLSession.state.name=State
meta.org.jkiss.dbeaver.ext.mysql.model.session.MySQLSession.state.description=State
meta.org.jkiss.dbeaver.ext.mysql.model.session.MySQLSession.activeQuery.name=Active Query
meta.org.jkiss.dbeaver.ext.mysql.model.session.MySQLSession.activeQuery.description=Currently executing SQL query
+meta.org.jkiss.dbeaver.ext.mysql.model.MySQLPackage.name.name=Name
+meta.org.jkiss.dbeaver.ext.mysql.model.MySQLPackage.description.name=Name
+meta.org.jkiss.dbeaver.ext.mysql.model.MySQLPackage.objectDefinitionText.name=Package Declaration
+meta.org.jkiss.dbeaver.ext.mysql.model.MySQLPackage.extendedDefinitionText.name=Package Body
meta.org.jkiss.dbeaver.ext.mysql.model.MySQLEvent.name.name=Event Name
meta.org.jkiss.dbeaver.ext.mysql.model.MySQLEvent.definer.name=Definer
diff --git a/plugins/org.jkiss.dbeaver.ext.mysql/plugin.xml b/plugins/org.jkiss.dbeaver.ext.mysql/plugin.xml
index 311d6eb1ac1a7ac064564377cfe0f3bb3bc27fb5..1a1693c78b65858f6c2aac4f80e4bedabccade64 100644
--- a/plugins/org.jkiss.dbeaver.ext.mysql/plugin.xml
+++ b/plugins/org.jkiss.dbeaver.ext.mysql/plugin.xml
@@ -92,6 +92,10 @@
+
+
+
+
@@ -223,6 +227,12 @@
+
+
+
+
{
+
+ public MySQLPackageBodyEditor()
+ {
+ }
+
+ @Override
+ protected boolean isReadOnly()
+ {
+ return false;
+ }
+
+ @Override
+ protected String getSourceText(DBRProgressMonitor monitor) throws DBException {
+ return ((DBPScriptObjectExt)getSourceObject()).getExtendedDefinitionText(monitor);
+ }
+
+ @Override
+ protected void setSourceText(DBRProgressMonitor monitor, String sourceText) {
+ getEditorInput().getPropertySource().setPropertyValue(
+ monitor,
+ "extendedDefinitionText",
+ sourceText);
+ }
+
+}
\ No newline at end of file
diff --git a/plugins/org.jkiss.dbeaver.ext.mysql/src/org/jkiss/dbeaver/ext/mysql/model/MySQLCatalog.java b/plugins/org.jkiss.dbeaver.ext.mysql/src/org/jkiss/dbeaver/ext/mysql/model/MySQLCatalog.java
index 834df2c6520d4d9cce922caaa6c7f53cdb4476e0..ae08d281772cb5b6b53b8229f4e9af6005e523ca 100644
--- a/plugins/org.jkiss.dbeaver.ext.mysql/src/org/jkiss/dbeaver/ext/mysql/model/MySQLCatalog.java
+++ b/plugins/org.jkiss.dbeaver.ext.mysql/src/org/jkiss/dbeaver/ext/mysql/model/MySQLCatalog.java
@@ -61,6 +61,7 @@ public class MySQLCatalog implements DBSCatalog, DBPSaveableObject, DBPRefreshab
final TableCache tableCache = new TableCache();
final ProceduresCache proceduresCache = new ProceduresCache();
+ final PackageCache packageCache = new PackageCache();
final TriggerCache triggerCache = new TriggerCache();
final ConstraintCache constraintCache = new ConstraintCache(tableCache);
final IndexCache indexCache = new IndexCache(tableCache);
@@ -184,7 +185,7 @@ public class MySQLCatalog implements DBSCatalog, DBPSaveableObject, DBPRefreshab
if (dbResult.next()) {
databaseSize = dbResult.getLong(1);
} else {
- databaseSize = 0l;
+ databaseSize = 0L;
}
}
}
@@ -264,6 +265,13 @@ public class MySQLCatalog implements DBSCatalog, DBPSaveableObject, DBPRefreshab
return proceduresCache.getObject(monitor, this, procName);
}
+ @Association
+ public Collection getPackages(DBRProgressMonitor monitor)
+ throws DBException
+ {
+ return packageCache.getAllObjects(monitor, this);
+ }
+
@Association
public Collection getTriggers(DBRProgressMonitor monitor)
throws DBException
@@ -685,6 +693,30 @@ public class MySQLCatalog implements DBSCatalog, DBPSaveableObject, DBPRefreshab
}
}
+ static class PackageCache extends JDBCObjectLookupCache {
+
+ @Override
+ protected MySQLPackage fetchObject(@NotNull JDBCSession session, @NotNull MySQLCatalog owner, @NotNull JDBCResultSet dbResult)
+ throws SQLException, DBException
+ {
+ return new MySQLPackage(owner, dbResult);
+ }
+
+ @Override
+ public JDBCStatement prepareLookupStatement(JDBCSession session, MySQLCatalog owner, MySQLPackage object, String objectName) throws SQLException {
+ JDBCPreparedStatement dbStat = session.prepareStatement(
+ "SELECT name,comment FROM mysql.proc\n" +
+ "WHERE db = ? AND type = 'PACKAGE'" +
+ (object == null && objectName == null ? "" : " \nAND name = ?")
+ );
+ dbStat.setString(1, owner.getName());
+ if (object != null || objectName != null) {
+ dbStat.setString(2, object != null ? object.getName() : objectName);
+ }
+ return dbStat;
+ }
+ }
+
static class TriggerCache extends JDBCObjectLookupCache {
@Override
diff --git a/plugins/org.jkiss.dbeaver.ext.mysql/src/org/jkiss/dbeaver/ext/mysql/model/MySQLPackage.java b/plugins/org.jkiss.dbeaver.ext.mysql/src/org/jkiss/dbeaver/ext/mysql/model/MySQLPackage.java
new file mode 100644
index 0000000000000000000000000000000000000000..477cee0210920b6a91d4fcdf5e3a5c622c2bd21a
--- /dev/null
+++ b/plugins/org.jkiss.dbeaver.ext.mysql/src/org/jkiss/dbeaver/ext/mysql/model/MySQLPackage.java
@@ -0,0 +1,225 @@
+/*
+ * DBeaver - Universal Database Manager
+ * Copyright (C) 2010-2018 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.ext.mysql.model;
+
+import org.jkiss.code.NotNull;
+import org.jkiss.dbeaver.DBException;
+import org.jkiss.dbeaver.model.*;
+import org.jkiss.dbeaver.model.exec.DBCException;
+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.JDBCUtils;
+import org.jkiss.dbeaver.model.impl.jdbc.cache.JDBCObjectCache;
+import org.jkiss.dbeaver.model.meta.Association;
+import org.jkiss.dbeaver.model.meta.Property;
+import org.jkiss.dbeaver.model.runtime.DBRProgressMonitor;
+import org.jkiss.dbeaver.model.struct.DBSObject;
+import org.jkiss.dbeaver.model.struct.DBSObjectContainer;
+import org.jkiss.dbeaver.model.struct.rdb.DBSProcedureContainer;
+
+import java.sql.ResultSet;
+import java.sql.SQLException;
+import java.util.Collection;
+import java.util.Map;
+
+/**
+ * GenericProcedure
+ */
+public class MySQLPackage
+ implements DBPScriptObject, DBPScriptObjectExt, DBSObjectContainer, DBPRefreshableObject, DBSProcedureContainer, DBPQualifiedObject
+{
+ private MySQLCatalog catalog;
+ private String name;
+ private String description;
+ private boolean persisted;
+ private final ProceduresCache proceduresCache = new ProceduresCache();
+ private String sourceDeclaration;
+ private String sourceDefinition;
+
+ public MySQLPackage(
+ MySQLCatalog catalog,
+ ResultSet dbResult)
+ {
+ this.catalog = catalog;
+ this.name = JDBCUtils.safeGetString(dbResult, "name");
+ this.description = JDBCUtils.safeGetString(dbResult, "comment");
+ this.persisted = true;
+ }
+
+ public MySQLPackage(MySQLCatalog catalog, String name)
+ {
+ this.catalog = catalog;
+ this.name = name;
+ this.persisted = false;
+ }
+
+ @Override
+ public DBPDataSource getDataSource() {
+ return catalog.getDataSource();
+ }
+
+ @Override
+ public DBSObject getParentObject() {
+ return catalog;
+ }
+
+ @Override
+ public boolean isPersisted() {
+ return persisted;
+ }
+
+ @Property(viewable = true, order = 1)
+ @Override
+ public String getName() {
+ return name;
+ }
+
+ @Override
+ public String getFullyQualifiedName(DBPEvaluationContext context) {
+ return DBUtils.getFullQualifiedName(getDataSource(),
+ getCatalog(),
+ this);
+ }
+
+ @Property(viewable = true, order = 100)
+ @Override
+ public String getDescription() {
+ return description;
+ }
+
+ public MySQLCatalog getCatalog() {
+ return catalog;
+ }
+
+ @Override
+ @Property(hidden = true, editable = true, updatable = true, order = -1)
+ public String getObjectDefinitionText(DBRProgressMonitor monitor, Map options) throws DBCException
+ {
+ if (sourceDeclaration == null && monitor != null) {
+ sourceDeclaration = readSource(monitor, false);
+ }
+ return sourceDeclaration;
+ }
+
+ public void setObjectDefinitionText(String sourceDeclaration)
+ {
+ this.sourceDeclaration = sourceDeclaration;
+ }
+
+ @Override
+ @Property(hidden = true, editable = true, updatable = true, order = -1)
+ public String getExtendedDefinitionText(DBRProgressMonitor monitor) throws DBException
+ {
+ if (sourceDefinition == null && monitor != null) {
+ sourceDefinition = readSource(monitor, true);
+ }
+ return sourceDefinition;
+ }
+
+ public void setExtendedDefinitionText(String source)
+ {
+ this.sourceDefinition = source;
+ }
+
+ @Association
+ public Collection getProcedures(DBRProgressMonitor monitor) throws DBException
+ {
+ return proceduresCache.getAllObjects(monitor, this);
+ }
+
+ @Override
+ public MySQLProcedure getProcedure(DBRProgressMonitor monitor, String uniqueName) throws DBException {
+ return proceduresCache.getObject(monitor, this, uniqueName);
+ }
+
+ @Override
+ public Collection extends DBSObject> getChildren(@NotNull DBRProgressMonitor monitor) throws DBException
+ {
+ return proceduresCache.getAllObjects(monitor, this);
+ }
+
+ @Override
+ public DBSObject getChild(@NotNull DBRProgressMonitor monitor, @NotNull String childName) throws DBException
+ {
+ return proceduresCache.getObject(monitor, this, childName);
+ }
+
+ @Override
+ public Class extends DBSObject> getChildType(@NotNull DBRProgressMonitor monitor) throws DBException
+ {
+ return MySQLProcedure.class;
+ }
+
+ @Override
+ public void cacheStructure(@NotNull DBRProgressMonitor monitor, int scope) throws DBException
+ {
+ proceduresCache.getAllObjects(monitor, this);
+ }
+
+ @Override
+ public DBSObject refreshObject(@NotNull DBRProgressMonitor monitor) throws DBException
+ {
+ this.proceduresCache.clearCache();
+ this.sourceDeclaration = null;
+ this.sourceDefinition = null;
+ return this;
+ }
+
+ private String readSource(DBRProgressMonitor monitor, boolean isBody) throws DBCException {
+ try (JDBCSession session = DBUtils.openMetaSession(monitor, getDataSource(), "Read package declaration")) {
+ try (JDBCPreparedStatement dbStat = session.prepareStatement("SHOW CREATE PACKAGE" + (isBody ? " BODY" : "") + " " + getFullyQualifiedName(DBPEvaluationContext.DML))) {
+ try (JDBCResultSet dbResult = dbStat.executeQuery()) {
+ if (dbResult.next()) {
+ return JDBCUtils.safeGetString(dbResult, (isBody ? "Create Package Body" : "Create Package"));
+ } else {
+ throw new DBCException("Package '" + getName() + "' not found");
+ }
+ }
+ }
+ } catch (SQLException e) {
+ throw new DBCException(e, getDataSource());
+ }
+ }
+
+ static class ProceduresCache extends JDBCObjectCache {
+
+ @Override
+ protected JDBCStatement prepareObjectsStatement(@NotNull JDBCSession session, @NotNull MySQLPackage owner)
+ throws SQLException
+ {
+ JDBCPreparedStatement dbStat = session.prepareStatement(
+ "SELECT P.*,CASE WHEN A.DATA_TYPE IS NULL THEN 'PROCEDURE' ELSE 'FUNCTION' END as PROCEDURE_TYPE FROM ALL_PROCEDURES P\n" +
+ "LEFT OUTER JOIN ALL_ARGUMENTS A ON A.OWNER=P.OWNER AND A.PACKAGE_NAME=P.OBJECT_NAME AND A.OBJECT_NAME=P.PROCEDURE_NAME AND A.ARGUMENT_NAME IS NULL AND A.DATA_LEVEL=0\n" +
+ "WHERE P.OWNER=? AND P.OBJECT_NAME=?\n" +
+ "ORDER BY P.PROCEDURE_NAME");
+ dbStat.setString(1, owner.getCatalog().getName());
+ dbStat.setString(2, owner.getName());
+ return dbStat;
+ }
+
+ @Override
+ protected MySQLProcedure fetchObject(@NotNull JDBCSession session, @NotNull MySQLPackage owner, @NotNull JDBCResultSet dbResult)
+ throws SQLException, DBException
+ {
+ return new MySQLProcedure(owner.getCatalog(), dbResult);
+ }
+
+ }
+
+}