Skip to content

Commit

Permalink
issue 2751 make sure drop schema drops everything (#2932)
Browse files Browse the repository at this point in the history
* issue 2751 make sure drop schema drops everything

Signed-off-by: Robin Arnold <[email protected]>

* issue 2751 fixed drop checks for Postgres, Db2 and Derby

Signed-off-by: Robin Arnold <[email protected]>

* issue 2751 idempotent schema drop for Db2, PostgreSQL and Derby

Signed-off-by: Robin Arnold <[email protected]>

* issue 2751 updates per review comments

Signed-off-by: Robin Arnold <[email protected]>

* copyright update

but really just to force a rebuild...

Signed-off-by: Lee Surprenant <[email protected]>

Co-authored-by: Lee Surprenant <[email protected]>
  • Loading branch information
punktilious and lmsurpre authored Nov 4, 2021
1 parent 7aaac5a commit b19bda2
Show file tree
Hide file tree
Showing 25 changed files with 1,136 additions and 10 deletions.
Original file line number Diff line number Diff line change
Expand Up @@ -10,6 +10,7 @@
import java.util.List;
import java.util.function.Supplier;

import com.ibm.fhir.database.utils.common.SchemaInfoObject;
import com.ibm.fhir.database.utils.model.CheckConstraint;
import com.ibm.fhir.database.utils.model.ColumnBase;
import com.ibm.fhir.database.utils.model.IdentityDef;
Expand Down Expand Up @@ -446,7 +447,6 @@ public void grantSequencePrivileges(String schemaName, String objectName, Collec
*/
public boolean doesTableExist(String schemaName, String objectName);


/**
* Create a database schema
*
Expand Down Expand Up @@ -584,4 +584,11 @@ public default boolean useSessionVariable() {
* @param selectClause
*/
public void createOrReplaceView(String schemaName, String objectName, String selectClause);

/**
* List the objects present in the given schema
* @param schemaName
* @return
*/
List<SchemaInfoObject> listSchemaObjects(String schemaName);
}
Original file line number Diff line number Diff line change
@@ -0,0 +1,51 @@
/*
* (C) Copyright IBM Corp. 2021
*
* SPDX-License-Identifier: Apache-2.0
*/

package com.ibm.fhir.database.utils.common;


/**
* A database object (table, index, view etc) existing within a schema
*/
public class SchemaInfoObject {
public enum Type {
FUNCTION,
INDEX,
PROCEDURE,
SEQUENCE,
TABLE,
VIEW
}

// The object type
private final Type type;

// The object name
private final String name;

public SchemaInfoObject(Type type, String name) {
this.type = type;
this.name = name;
}

@Override
public String toString() {
return type.name() + ":" + name;
}
/**
* @return the type
*/
public Type getType() {
return type;
}

/**
* @return the name
*/
public String getName() {
return name;
}
}
Original file line number Diff line number Diff line change
Expand Up @@ -35,6 +35,7 @@
import com.ibm.fhir.database.utils.common.CommonDatabaseAdapter;
import com.ibm.fhir.database.utils.common.DataDefinitionUtil;
import com.ibm.fhir.database.utils.common.DropColumn;
import com.ibm.fhir.database.utils.common.SchemaInfoObject;
import com.ibm.fhir.database.utils.model.CheckConstraint;
import com.ibm.fhir.database.utils.model.ColumnBase;
import com.ibm.fhir.database.utils.model.IdentityDef;
Expand Down Expand Up @@ -639,4 +640,19 @@ public void reorgTable(String schemaName, String tableName) {
Db2Reorg cmd = new Db2Reorg(schemaName, tableName);
runStatement(cmd);
}

@Override
public List<SchemaInfoObject> listSchemaObjects(String schemaName) {
List<SchemaInfoObject> result = new ArrayList<>();
Db2ListTablesForSchema listTables = new Db2ListTablesForSchema(schemaName);
result.addAll(runStatement(listTables));

Db2ListViewsForSchema listViews = new Db2ListViewsForSchema(schemaName);
result.addAll(runStatement(listViews));

Db2ListSequencesForSchema listSequences = new Db2ListSequencesForSchema(schemaName);
result.addAll(runStatement(listSequences));

return result;
}
}
Original file line number Diff line number Diff line change
@@ -0,0 +1,57 @@
/*
* (C) Copyright IBM Corp. 2021
*
* SPDX-License-Identifier: Apache-2.0
*/

package com.ibm.fhir.database.utils.db2;

import java.sql.Connection;
import java.sql.PreparedStatement;
import java.sql.ResultSet;
import java.sql.SQLException;
import java.util.ArrayList;
import java.util.List;

import com.ibm.fhir.database.utils.api.IDatabaseSupplier;
import com.ibm.fhir.database.utils.api.IDatabaseTranslator;
import com.ibm.fhir.database.utils.common.DataDefinitionUtil;
import com.ibm.fhir.database.utils.common.SchemaInfoObject;
import com.ibm.fhir.database.utils.common.SchemaInfoObject.Type;

/**
* DAO to fetch the names of sequences in the given schema
*/
public class Db2ListSequencesForSchema implements IDatabaseSupplier<List<SchemaInfoObject>> {

// The schema of the table
private final String schemaName;

/**
* Public constructor
* @param schemaName
*/
public Db2ListSequencesForSchema(String schemaName) {
this.schemaName = DataDefinitionUtil.assertValidName(schemaName);
}

@Override
public List<SchemaInfoObject> run(IDatabaseTranslator translator, Connection c) {
List<SchemaInfoObject> result = new ArrayList<>();
// Grab the list of sequences for the configured schema from the DB2 catalog
final String sql = "SELECT seqname FROM SYSCAT.SEQUENCES WHERE seqschema = ?";

try (PreparedStatement ps = c.prepareStatement(sql)) {
ps.setString(1, schemaName);
ResultSet rs = ps.executeQuery();
while (rs.next()) {
result.add(new SchemaInfoObject(Type.SEQUENCE, rs.getString(1)));
}
}
catch (SQLException x) {
throw translator.translate(x);
}

return result;
}
}
Original file line number Diff line number Diff line change
@@ -0,0 +1,57 @@
/*
* (C) Copyright IBM Corp. 2021
*
* SPDX-License-Identifier: Apache-2.0
*/

package com.ibm.fhir.database.utils.db2;

import java.sql.Connection;
import java.sql.PreparedStatement;
import java.sql.ResultSet;
import java.sql.SQLException;
import java.util.ArrayList;
import java.util.List;

import com.ibm.fhir.database.utils.api.IDatabaseSupplier;
import com.ibm.fhir.database.utils.api.IDatabaseTranslator;
import com.ibm.fhir.database.utils.common.DataDefinitionUtil;
import com.ibm.fhir.database.utils.common.SchemaInfoObject;
import com.ibm.fhir.database.utils.common.SchemaInfoObject.Type;

/**
* DAO to fetch the names of tables in the given schema
*/
public class Db2ListTablesForSchema implements IDatabaseSupplier<List<SchemaInfoObject>> {

// The schema of the table
private final String schemaName;

/**
* Public constructor
* @param schemaName
*/
public Db2ListTablesForSchema(String schemaName) {
this.schemaName = DataDefinitionUtil.assertValidName(schemaName);
}

@Override
public List<SchemaInfoObject> run(IDatabaseTranslator translator, Connection c) {
List<SchemaInfoObject> result = new ArrayList<>();
// Grab the list of tables for the configured schema from the DB2 catalog
final String sql = "SELECT tabname FROM SYSCAT.TABLES WHERE tabschema = ?";

try (PreparedStatement ps = c.prepareStatement(sql)) {
ps.setString(1, schemaName);
ResultSet rs = ps.executeQuery();
while (rs.next()) {
result.add(new SchemaInfoObject(Type.TABLE, rs.getString(1)));
}
}
catch (SQLException x) {
throw translator.translate(x);
}

return result;
}
}
Original file line number Diff line number Diff line change
@@ -0,0 +1,57 @@
/*
* (C) Copyright IBM Corp. 2021
*
* SPDX-License-Identifier: Apache-2.0
*/

package com.ibm.fhir.database.utils.db2;

import java.sql.Connection;
import java.sql.PreparedStatement;
import java.sql.ResultSet;
import java.sql.SQLException;
import java.util.ArrayList;
import java.util.List;

import com.ibm.fhir.database.utils.api.IDatabaseSupplier;
import com.ibm.fhir.database.utils.api.IDatabaseTranslator;
import com.ibm.fhir.database.utils.common.DataDefinitionUtil;
import com.ibm.fhir.database.utils.common.SchemaInfoObject;
import com.ibm.fhir.database.utils.common.SchemaInfoObject.Type;

/**
* DAO to fetch the names of views in the given schema
*/
public class Db2ListViewsForSchema implements IDatabaseSupplier<List<SchemaInfoObject>> {

// The schema of the table
private final String schemaName;

/**
* Public constructor
* @param schemaName
*/
public Db2ListViewsForSchema(String schemaName) {
this.schemaName = DataDefinitionUtil.assertValidName(schemaName);
}

@Override
public List<SchemaInfoObject> run(IDatabaseTranslator translator, Connection c) {
List<SchemaInfoObject> result = new ArrayList<>();
// Grab the list of views for the configured schema from the DB2 catalog
final String sql = "SELECT viewname FROM SYSCAT.VIEWS WHERE viewschema = ?";

try (PreparedStatement ps = c.prepareStatement(sql)) {
ps.setString(1, schemaName);
ResultSet rs = ps.executeQuery();
while (rs.next()) {
result.add(new SchemaInfoObject(Type.VIEW, rs.getString(1)));
}
}
catch (SQLException x) {
throw translator.translate(x);
}

return result;
}
}
Original file line number Diff line number Diff line change
Expand Up @@ -6,6 +6,7 @@

package com.ibm.fhir.database.utils.derby;

import java.util.ArrayList;
import java.util.Collection;
import java.util.List;
import java.util.Set;
Expand All @@ -24,6 +25,7 @@
import com.ibm.fhir.database.utils.common.CommonDatabaseAdapter;
import com.ibm.fhir.database.utils.common.DataDefinitionUtil;
import com.ibm.fhir.database.utils.common.GetSequenceNextValueDAO;
import com.ibm.fhir.database.utils.common.SchemaInfoObject;
import com.ibm.fhir.database.utils.model.CheckConstraint;
import com.ibm.fhir.database.utils.model.ColumnBase;
import com.ibm.fhir.database.utils.model.ForeignKeyConstraint;
Expand All @@ -42,7 +44,7 @@ public class DerbyAdapter extends CommonDatabaseAdapter {
// Different warning messages we track so that we only have to report them once
private enum MessageKey {
MULTITENANCY, CREATE_VAR, CREATE_PERM, ENABLE_ROW_ACCESS, DISABLE_ROW_ACCESS, PARTITIONING,
ROW_TYPE, ROW_ARR_TYPE, DROP_TYPE, CREATE_PROC, DROP_PROC, TABLESPACE, ALTER_TABLE_SEQ_CACHE
ROW_TYPE, ROW_ARR_TYPE, DROP_TYPE, CREATE_PROC, DROP_PROC, DROP_PERM, TABLESPACE, ALTER_TABLE_SEQ_CACHE
}

// Just warn once for each unique message key. This cleans up build logs a lot
Expand Down Expand Up @@ -154,6 +156,11 @@ public void dropProcedure(String schemaName, String procedureName) {
warnOnce(MessageKey.DROP_PROC, "Drop procedure not supported in Derby");
}

@Override
public void dropPermission(String schemaName, String permissionName) {
warnOnce(MessageKey.DROP_PERM, "Drop permission not supported in Derby");
}

@Override
public void createTablespace(String tablespaceName) {
logger.fine("Create tablespace not supported in Derby");
Expand Down Expand Up @@ -212,6 +219,9 @@ public void dropSequence(String schemaName, String sequenceName) {
runStatement(ddl);
} catch (UndefinedNameException x) {
logger.warning(ddl + "; Sequence not found");
} catch (Exception sx) {
logger.warning("Drop sequence failed - DDL: " + ddl);
throw sx;
}
}

Expand Down Expand Up @@ -367,4 +377,19 @@ public void createOrReplaceView(String schemaName, String viewName, String selec
}
createView(schemaName, viewName, selectClause);
}

@Override
public List<SchemaInfoObject> listSchemaObjects(String schemaName) {
List<SchemaInfoObject> result = new ArrayList<>();
DerbyListTablesForSchema listTables = new DerbyListTablesForSchema(schemaName);
result.addAll(runStatement(listTables));

DerbyListViewsForSchema listViews = new DerbyListViewsForSchema(schemaName);
result.addAll(runStatement(listViews));

DerbyListSequencesForSchema listSequences = new DerbyListSequencesForSchema(schemaName);
result.addAll(runStatement(listSequences));

return result;
}
}
Loading

0 comments on commit b19bda2

Please sign in to comment.