/*
* DBeaver - Universal Database Manager
* Copyright (C) 2010-2017 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.code.Nullable;
import org.jkiss.dbeaver.DBException;
import org.jkiss.dbeaver.ext.mysql.MySQLConstants;
import org.jkiss.dbeaver.model.*;
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.JDBCCompositeCache;
import org.jkiss.dbeaver.model.impl.jdbc.cache.JDBCObjectCache;
import org.jkiss.dbeaver.model.impl.jdbc.cache.JDBCStructLookupCache;
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.sql.SQLUtils;
import org.jkiss.dbeaver.model.struct.DBSEntity;
import org.jkiss.dbeaver.model.struct.DBSEntityConstraintType;
import org.jkiss.dbeaver.model.struct.DBSObject;
import org.jkiss.dbeaver.model.struct.rdb.DBSCatalog;
import org.jkiss.dbeaver.model.struct.rdb.DBSIndexType;
import org.jkiss.dbeaver.model.struct.rdb.DBSProcedureContainer;
import org.jkiss.dbeaver.model.struct.rdb.DBSProcedureParameterKind;
import org.jkiss.utils.CommonUtils;
import java.sql.DatabaseMetaData;
import java.sql.ResultSet;
import java.sql.SQLException;
import java.util.Collection;
import java.util.List;
/**
* GenericCatalog
*/
public class MySQLCatalog implements DBSCatalog, DBPSaveableObject, DBPRefreshableObject, DBPSystemObject, DBSProcedureContainer
{
final TableCache tableCache = new TableCache();
final ProceduresCache proceduresCache = new ProceduresCache();
final TriggerCache triggerCache = new TriggerCache();
final ConstraintCache constraintCache = new ConstraintCache(tableCache);
final IndexCache indexCache = new IndexCache(tableCache);
final EventCache eventCache = new EventCache();
private MySQLDataSource dataSource;
private String name;
private MySQLCharset defaultCharset;
private MySQLCollation defaultCollation;
private String sqlPath;
private boolean persisted;
public MySQLCatalog(MySQLDataSource dataSource, ResultSet dbResult)
{
tableCache.setCaseSensitive(false);
this.dataSource = dataSource;
if (dbResult != null) {
this.name = JDBCUtils.safeGetString(dbResult, MySQLConstants.COL_SCHEMA_NAME);
defaultCharset = dataSource.getCharset(JDBCUtils.safeGetString(dbResult, MySQLConstants.COL_DEFAULT_CHARACTER_SET_NAME));
defaultCollation = dataSource.getCollation(JDBCUtils.safeGetString(dbResult, MySQLConstants.COL_DEFAULT_COLLATION_NAME));
sqlPath = JDBCUtils.safeGetString(dbResult, MySQLConstants.COL_SQL_PATH);
persisted = true;
} else {
defaultCharset = dataSource.getCharset("utf8");
defaultCollation = dataSource.getCollation("utf8_general_ci");
sqlPath = "";
persisted = false;
}
}
@Override
public DBSObject getParentObject()
{
return dataSource.getContainer();
}
@NotNull
@Override
public MySQLDataSource getDataSource()
{
return dataSource;
}
@NotNull
@Override
@Property(viewable = true, editable = true, order = 1)
public String getName()
{
return name;
}
public void setName(String name)
{
this.name = name;
}
@Override
public boolean isPersisted()
{
return persisted;
}
@Override
public void setPersisted(boolean persisted)
{
this.persisted = persisted;
}
@Nullable
@Override
public String getDescription()
{
return null;
}
@Property(viewable = true, order = 2)
public MySQLCharset getDefaultCharset()
{
return defaultCharset;
}
public void setDefaultCharset(MySQLCharset defaultCharset)
{
this.defaultCharset = defaultCharset;
}
@Property(viewable = true, order = 3)
public MySQLCollation getDefaultCollation()
{
return defaultCollation;
}
public void setDefaultCollation(MySQLCollation defaultCollation)
{
this.defaultCollation = defaultCollation;
}
@Property(viewable = true, order = 3)
public String getSqlPath()
{
return sqlPath;
}
void setSqlPath(String sqlPath)
{
this.sqlPath = sqlPath;
}
public TableCache getTableCache()
{
return tableCache;
}
public ProceduresCache getProceduresCache()
{
return proceduresCache;
}
public TriggerCache getTriggerCache()
{
return triggerCache;
}
public ConstraintCache getConstraintCache()
{
return constraintCache;
}
public IndexCache getIndexCache()
{
return indexCache;
}
public EventCache getEventCache() {
return eventCache;
}
@Association
public Collection<MySQLTableIndex> getIndexes(DBRProgressMonitor monitor)
throws DBException
{
return indexCache.getObjects(monitor, this, null);
}
@Association
public Collection<MySQLTable> getTables(DBRProgressMonitor monitor)
throws DBException
{
return tableCache.getTypedObjects(monitor, this, MySQLTable.class);
}
public MySQLTable getTable(DBRProgressMonitor monitor, String name)
throws DBException
{
return tableCache.getObject(monitor, this, name, MySQLTable.class);
}
@Association
public Collection<MySQLView> getViews(DBRProgressMonitor monitor)
throws DBException
{
return tableCache.getTypedObjects(monitor, this, MySQLView.class);
}
@Association
public Collection<MySQLProcedure> getProcedures(DBRProgressMonitor monitor)
throws DBException
{
return proceduresCache.getAllObjects(monitor, this);
}
public MySQLProcedure getProcedure(DBRProgressMonitor monitor, String procName)
throws DBException
{
return proceduresCache.getObject(monitor, this, procName);
}
@Association
public Collection<MySQLTrigger> getTriggers(DBRProgressMonitor monitor)
throws DBException
{
return triggerCache.getAllObjects(monitor, this);
}
public MySQLTrigger getTrigger(DBRProgressMonitor monitor, String name)
throws DBException
{
return triggerCache.getObject(monitor, this, name);
}
@Association
public Collection<MySQLEvent> getEvents(DBRProgressMonitor monitor)
throws DBException
{
return eventCache.getAllObjects(monitor, this);
}
@Override
public Collection<MySQLTableBase> getChildren(@NotNull DBRProgressMonitor monitor)
throws DBException
{
return tableCache.getAllObjects(monitor, this);
}
@Override
public MySQLTableBase getChild(@NotNull DBRProgressMonitor monitor, @NotNull String childName)
throws DBException
{
return tableCache.getObject(monitor, this, childName);
}
@Override
public Class<? extends DBSEntity> getChildType(@NotNull DBRProgressMonitor monitor)
throws DBException
{
return MySQLTable.class;
}
@Override
public synchronized void cacheStructure(@NotNull DBRProgressMonitor monitor, int scope)
throws DBException
{
monitor.subTask("Cache tables");
tableCache.getAllObjects(monitor, this);
if ((scope & STRUCT_ATTRIBUTES) != 0) {
monitor.subTask("Cache table columns");
tableCache.loadChildren(monitor, this, null);
}
if ((scope & STRUCT_ASSOCIATIONS) != 0) {
monitor.subTask("Cache table constraints");
constraintCache.getAllObjects(monitor, this);
}
}
@Override
public synchronized DBSObject refreshObject(@NotNull DBRProgressMonitor monitor)
throws DBException
{
tableCache.clearCache();
indexCache.clearCache();
constraintCache.clearCache();
proceduresCache.clearCache();
triggerCache.clearCache();
return this;
}
@Override
public boolean isSystem()
{
return MySQLConstants.INFO_SCHEMA_NAME.equalsIgnoreCase(getName()) || MySQLConstants.MYSQL_SCHEMA_NAME.equalsIgnoreCase(getName());
}
@Override
public String toString()
{
return name + " [" + dataSource.getContainer().getName() + "]";
}
public static class TableCache extends JDBCStructLookupCache<MySQLCatalog, MySQLTableBase, MySQLTableColumn> {
TableCache()
{
super(JDBCConstants.TABLE_NAME);
}
@NotNull
@Override
public JDBCStatement prepareLookupStatement(@NotNull JDBCSession session, @NotNull MySQLCatalog owner, @Nullable MySQLTableBase object, @Nullable String objectName) throws SQLException {
StringBuilder sql = new StringBuilder();
sql.append("SHOW FULL TABLES FROM ").append(DBUtils.getQuotedIdentifier(owner));
if (object != null || objectName != null) {
sql.append(" LIKE ").append(SQLUtils.quoteString(object != null ? object.getName() : objectName));
}
return session.prepareStatement(sql.toString());
/*
StringBuilder sql = new StringBuilder();
sql.append("SHOW FULL TABLES FROM ").append(DBUtils.getQuotedIdentifier(owner));
String tableNameCol = "Tables_in_" + owner.getName();
if (object != null || objectName != null) {
sql.append(" WHERE ").append(tableNameCol).append(" LIKE ").append(SQLUtils.quoteString(object != null ? object.getName() : objectName));
} else {
DBSObjectFilter tableFilters = owner.getDataSource().getContainer().getObjectFilter(MySQLTable.class, owner, false);
if (tableFilters != null && !tableFilters.isEmpty()) {
sql.append(" WHERE 1=1");
for (String incName : CommonUtils.safeCollection(tableFilters.getInclude())) {
sql.append(" AND ").append(tableNameCol).append(" LIKE ").append(SQLUtils.quoteString(incName));
}
for (String incName : CommonUtils.safeCollection(tableFilters.getExclude())) {
sql.append(" AND ").append(tableNameCol).append(" NOT LIKE ").append(SQLUtils.quoteString(incName));
}
}
}
*/
}
@Override
protected MySQLTableBase fetchObject(@NotNull JDBCSession session, @NotNull MySQLCatalog owner, @NotNull JDBCResultSet dbResult)
throws SQLException, DBException
{
final String tableType = JDBCUtils.safeGetString(dbResult, MySQLConstants.COL_TABLE_TYPE);
if (tableType != null && tableType.contains("VIEW")) {
return new MySQLView(owner, dbResult);
} else {
return new MySQLTable(owner, dbResult);
}
}
@Override
protected JDBCStatement prepareChildrenStatement(@NotNull JDBCSession session, @NotNull MySQLCatalog owner, @Nullable MySQLTableBase forTable)
throws SQLException
{
StringBuilder sql = new StringBuilder();
sql
.append("SELECT * FROM ").append(MySQLConstants.META_TABLE_COLUMNS)
.append(" WHERE ").append(MySQLConstants.COL_TABLE_SCHEMA).append("=?");
if (forTable != null) {
sql.append(" AND ").append(MySQLConstants.COL_TABLE_NAME).append("=?");
}
sql.append(" ORDER BY ").append(MySQLConstants.COL_ORDINAL_POSITION);
JDBCPreparedStatement dbStat = session.prepareStatement(sql.toString());
dbStat.setString(1, owner.getName());
if (forTable != null) {
dbStat.setString(2, forTable.getName());
}
return dbStat;
}
@Override
protected MySQLTableColumn fetchChild(@NotNull JDBCSession session, @NotNull MySQLCatalog owner, @NotNull MySQLTableBase table, @NotNull JDBCResultSet dbResult)
throws SQLException, DBException
{
return new MySQLTableColumn(table, dbResult);
}
}
/**
* Index cache implementation
*/
static class IndexCache extends JDBCCompositeCache<MySQLCatalog, MySQLTable, MySQLTableIndex, MySQLTableIndexColumn> {
IndexCache(TableCache tableCache)
{
super(tableCache, MySQLTable.class, MySQLConstants.COL_TABLE_NAME, MySQLConstants.COL_INDEX_NAME);
}
@NotNull
@Override
protected JDBCStatement prepareObjectsStatement(JDBCSession session, MySQLCatalog owner, MySQLTable forTable)
throws SQLException
{
StringBuilder sql = new StringBuilder();
sql
.append("SELECT * FROM ").append(MySQLConstants.META_TABLE_STATISTICS)
.append(" WHERE ").append(MySQLConstants.COL_TABLE_SCHEMA).append("=?");
if (forTable != null) {
sql.append(" AND ").append(MySQLConstants.COL_TABLE_NAME).append("=?");
}
sql.append(" ORDER BY ").append(MySQLConstants.COL_INDEX_NAME).append(",").append(MySQLConstants.COL_SEQ_IN_INDEX);
JDBCPreparedStatement dbStat = session.prepareStatement(sql.toString());
dbStat.setString(1, owner.getName());
if (forTable != null) {
dbStat.setString(2, forTable.getName());
}
return dbStat;
}
@Nullable
@Override
protected MySQLTableIndex fetchObject(JDBCSession session, MySQLCatalog owner, MySQLTable parent, String indexName, JDBCResultSet dbResult)
throws SQLException, DBException
{
String indexTypeName = JDBCUtils.safeGetString(dbResult, MySQLConstants.COL_INDEX_TYPE);
DBSIndexType indexType;
if (MySQLConstants.INDEX_TYPE_BTREE.getId().equals(indexTypeName)) {
indexType = MySQLConstants.INDEX_TYPE_BTREE;
} else if (MySQLConstants.INDEX_TYPE_FULLTEXT.getId().equals(indexTypeName)) {
indexType = MySQLConstants.INDEX_TYPE_FULLTEXT;
} else if (MySQLConstants.INDEX_TYPE_HASH.getId().equals(indexTypeName)) {
indexType = MySQLConstants.INDEX_TYPE_HASH;
} else if (MySQLConstants.INDEX_TYPE_RTREE.getId().equals(indexTypeName)) {
indexType = MySQLConstants.INDEX_TYPE_RTREE;
} else {
indexType = DBSIndexType.OTHER;
}
return new MySQLTableIndex(
parent,
indexName,
indexType,
dbResult);
}
@Nullable
@Override
protected MySQLTableIndexColumn[] fetchObjectRow(
JDBCSession session,
MySQLTable parent, MySQLTableIndex object, JDBCResultSet dbResult)
throws SQLException, DBException
{
int ordinalPosition = JDBCUtils.safeGetInt(dbResult, MySQLConstants.COL_SEQ_IN_INDEX);
String columnName = JDBCUtils.safeGetStringTrimmed(dbResult, MySQLConstants.COL_COLUMN_NAME);
String ascOrDesc = JDBCUtils.safeGetStringTrimmed(dbResult, MySQLConstants.COL_COLLATION);
boolean nullable = "YES".equals(JDBCUtils.safeGetStringTrimmed(dbResult, MySQLConstants.COL_NULLABLE));
String subPart = JDBCUtils.safeGetStringTrimmed(dbResult, MySQLConstants.COL_SUB_PART);
MySQLTableColumn tableColumn = columnName == null ? null : parent.getAttribute(session.getProgressMonitor(), columnName);
if (tableColumn == null) {
log.debug("Column '" + columnName + "' not found in table '" + parent.getName() + "' for index '" + object.getName() + "'");
return null;
}
return new MySQLTableIndexColumn[] { new MySQLTableIndexColumn(
object,
tableColumn,
ordinalPosition,
"A".equalsIgnoreCase(ascOrDesc),
nullable,
subPart)
};
}
@Override
protected void cacheChildren(DBRProgressMonitor monitor, MySQLTableIndex index, List<MySQLTableIndexColumn> rows)
{
index.setColumns(rows);
}
}
/**
* Constraint cache implementation
*/
static class ConstraintCache extends JDBCCompositeCache<MySQLCatalog, MySQLTable, MySQLTableConstraint, MySQLTableConstraintColumn> {
ConstraintCache(TableCache tableCache)
{
super(tableCache, MySQLTable.class, MySQLConstants.COL_TABLE_NAME, MySQLConstants.COL_CONSTRAINT_NAME);
}
@NotNull
@Override
protected JDBCStatement prepareObjectsStatement(JDBCSession session, MySQLCatalog owner, MySQLTable forTable)
throws SQLException
{
StringBuilder sql = new StringBuilder(500);
sql.append(
"SELECT kc.CONSTRAINT_NAME,kc.TABLE_NAME,kc.COLUMN_NAME,kc.ORDINAL_POSITION\n" +
"FROM INFORMATION_SCHEMA.KEY_COLUMN_USAGE kc WHERE kc.TABLE_SCHEMA=? AND kc.REFERENCED_TABLE_NAME IS NULL");
if (forTable != null) {
sql.append(" AND kc.TABLE_NAME=?");
}
sql.append("\nORDER BY kc.CONSTRAINT_NAME,kc.ORDINAL_POSITION");
JDBCPreparedStatement dbStat = session.prepareStatement(sql.toString());
dbStat.setString(1, owner.getName());
if (forTable != null) {
dbStat.setString(2, forTable.getName());
}
return dbStat;
}
@Nullable
@Override
protected MySQLTableConstraint fetchObject(JDBCSession session, MySQLCatalog owner, MySQLTable parent, String constraintName, JDBCResultSet dbResult)
throws SQLException, DBException
{
if (constraintName.equals("PRIMARY")) {
return new MySQLTableConstraint(
parent, constraintName, null, DBSEntityConstraintType.PRIMARY_KEY, true);
} else {
return new MySQLTableConstraint(
parent, constraintName, null, DBSEntityConstraintType.UNIQUE_KEY, true);
}
}
@Nullable
@Override
protected MySQLTableConstraintColumn[] fetchObjectRow(
JDBCSession session,
MySQLTable parent, MySQLTableConstraint object, JDBCResultSet dbResult)
throws SQLException, DBException
{
String columnName = JDBCUtils.safeGetString(dbResult, MySQLConstants.COL_COLUMN_NAME);
MySQLTableColumn column = parent.getAttribute(session.getProgressMonitor(), columnName);
if (column == null) {
log.warn("Column '" + columnName + "' not found in table '" + parent.getFullyQualifiedName(DBPEvaluationContext.DDL) + "'");
return null;
}
int ordinalPosition = JDBCUtils.safeGetInt(dbResult, MySQLConstants.COL_ORDINAL_POSITION);
return new MySQLTableConstraintColumn[] { new MySQLTableConstraintColumn(
object,
column,
ordinalPosition) };
}
@Override
protected void cacheChildren(DBRProgressMonitor monitor, MySQLTableConstraint constraint, List<MySQLTableConstraintColumn> rows)
{
constraint.setColumns(rows);
}
}
/**
* Procedures cache implementation
*/
static class ProceduresCache extends JDBCStructLookupCache<MySQLCatalog, MySQLProcedure, MySQLProcedureParameter> {
ProceduresCache()
{
super(JDBCConstants.PROCEDURE_NAME);
}
@Override
protected MySQLProcedure fetchObject(@NotNull JDBCSession session, @NotNull MySQLCatalog owner, @NotNull JDBCResultSet dbResult)
throws SQLException, DBException
{
return new MySQLProcedure(owner, dbResult);
}
@Override
protected JDBCStatement prepareChildrenStatement(@NotNull JDBCSession session, @NotNull MySQLCatalog owner, @Nullable MySQLProcedure procedure)
throws SQLException
{
// Load procedure columns through MySQL metadata
// There is no metadata table about proc/func columns -
// it should be parsed from SHOW CREATE PROCEDURE/FUNCTION query
// Lets driver do it instead of me
return session.getMetaData().getProcedureColumns(
owner.getName(),
null,
procedure == null ? null : procedure.getName(),
"%").getSourceStatement();
}
@Override
protected MySQLProcedureParameter fetchChild(@NotNull JDBCSession session, @NotNull MySQLCatalog owner, @NotNull MySQLProcedure parent, @NotNull JDBCResultSet dbResult)
throws SQLException, DBException
{
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);
//int radix = JDBCUtils.safeGetInt(dbResult, JDBCConstants.RADIX);
//DBSDataType dataType = getDataSourceContainer().getInfo().getSupportedDataType(typeName);
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);
}
@NotNull
@Override
public JDBCStatement prepareLookupStatement(@NotNull JDBCSession session, @NotNull MySQLCatalog owner, @Nullable MySQLProcedure object, @Nullable 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 + "=?") +
"\nORDER BY " + MySQLConstants.COL_ROUTINE_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 JDBCObjectCache<MySQLCatalog, MySQLTrigger> {
@Override
protected JDBCStatement prepareObjectsStatement(@NotNull JDBCSession session, @NotNull MySQLCatalog owner)
throws SQLException
{
return session.prepareStatement(
"SHOW FULL TRIGGERS FROM " + DBUtils.getQuotedIdentifier(owner));
}
@Override
protected MySQLTrigger fetchObject(@NotNull JDBCSession session, @NotNull MySQLCatalog owner, @NotNull JDBCResultSet dbResult)
throws SQLException, DBException
{
String tableName = JDBCUtils.safeGetString(dbResult, "TABLE");
MySQLTable triggerTable = CommonUtils.isEmpty(tableName) ? null : owner.getTable(session.getProgressMonitor(), tableName);
return new MySQLTrigger(owner, triggerTable, dbResult);
}
}
static class EventCache extends JDBCObjectCache<MySQLCatalog, MySQLEvent> {
@Override
protected JDBCStatement prepareObjectsStatement(@NotNull JDBCSession session, @NotNull MySQLCatalog owner)
throws SQLException
{
final JDBCPreparedStatement dbStat = session.prepareStatement(
"SELECT * FROM information_schema.EVENTS WHERE EVENT_SCHEMA=?");
dbStat.setString(1, DBUtils.getQuotedIdentifier(owner));
return dbStat;
}
@Override
protected MySQLEvent fetchObject(@NotNull JDBCSession session, @NotNull MySQLCatalog owner, @NotNull JDBCResultSet dbResult)
throws SQLException, DBException
{
return new MySQLEvent(owner, dbResult);
}
}
}