Skip to content

Commit

Permalink
[Database][BackupRestore] Better handling which table to drop-recreat…
Browse files Browse the repository at this point in the history
…e and which to delete. Also automatically get default schema for user and database
  • Loading branch information
dslaveykov committed Nov 22, 2018
1 parent 97df8c4 commit 348b80c
Show file tree
Hide file tree
Showing 6 changed files with 182 additions and 128 deletions.
Expand Up @@ -50,6 +50,7 @@
import com.axway.ats.core.dbaccess.DbConnection;
import com.axway.ats.core.dbaccess.oracle.DbConnOracle;
import com.axway.ats.core.utils.IoUtils;
import com.axway.ats.core.utils.StringUtils;
import com.axway.ats.environment.AdditionalAction;
import com.axway.ats.environment.EnvironmentUnit;
import com.axway.ats.environment.database.DatabaseEnvironmentUnit;
Expand Down Expand Up @@ -361,6 +362,14 @@ private EnvironmentUnit parseDbEnvironment( Node dbEnvironmentNode,

if (dbChildNode.getNodeName().equals(TABLE)) {
String tableName = dbChildNode.getAttributes().getNamedItem("name").getNodeValue();
String schemaName = new String();
String[] tableNames = tableName.split("\\.");
if(!StringUtils.isNullOrEmpty(tableName) && tableNames.length > 1) {
// Note that if the table name contains dot (.), even if the table name is escaped properly, according to the database server,
// we will consider the presence of dot as a sign that the table names is of the format <schema_name>.<table_name>
schemaName = tableNames[0];
tableName = tableNames[1];
}

String[] columnsToExclude = {};
if (dbChildNode.getAttributes().getNamedItem("columnsToExclude") != null) {
Expand All @@ -370,7 +379,7 @@ private EnvironmentUnit parseDbEnvironment( Node dbEnvironmentNode,
.split(",");
}

DbTable dbTable = new DbTable(tableName, new String(), Arrays.asList(columnsToExclude));
DbTable dbTable = new DbTable(tableName, schemaName, Arrays.asList(columnsToExclude));
// parse db table 'lock' attribute
if (dbChildNode.getAttributes().getNamedItem("lock") != null) {

Expand Down
Expand Up @@ -327,6 +327,19 @@ public void setDropTables( boolean dropEntireTable ) {
this.dropEntireTable = dropEntireTable;

}

/**
* <p>Whether to drop table can be specified by either {@link #setDropTables(boolean)} or {@link DbTable#setDropTable(boolean)}</p>
* This method here wraps the logic that determines what must be done for a particular table
* */
protected boolean shouldDropTable( DbTable table ) {

if (table.isDropTable() == null) {
return dropEntireTable;
} else {
return table.isDropTable();
}
}

protected abstract void writeDeleteStatements( Writer fileWriter ) throws IOException;

Expand Down
Expand Up @@ -32,17 +32,18 @@
import java.util.HashMap;
import java.util.List;
import java.util.Map;
import java.util.Scanner;
import java.util.Map.Entry;
import java.util.Scanner;

import org.apache.log4j.Logger;

import com.axway.ats.common.dbaccess.DbQuery;
import com.axway.ats.common.systemproperties.AtsSystemProperties;
import com.axway.ats.config.exceptions.NoSuchPropertyException;
import com.axway.ats.core.dbaccess.ColumnDescription;
import com.axway.ats.core.dbaccess.ConnectionPool;
import com.axway.ats.core.dbaccess.DbRecordValue;
import com.axway.ats.core.dbaccess.DbRecordValuesList;
import com.axway.ats.core.dbaccess.DbReturnModes;
import com.axway.ats.core.dbaccess.DbUtils;
import com.axway.ats.core.dbaccess.MssqlColumnDescription;
import com.axway.ats.core.dbaccess.exceptions.DbException;
Expand All @@ -53,21 +54,19 @@
import com.axway.ats.environment.database.exceptions.ColumnHasNoDefaultValueException;
import com.axway.ats.environment.database.exceptions.DatabaseEnvironmentCleanupException;
import com.axway.ats.environment.database.model.DbTable;
import com.axway.ats.harness.config.CommonConfigurator;

class MssqlEnvironmentHandler extends AbstractEnvironmentHandler {

// used to provide a default schema for mssql operations
// in no such property is found, ATS uses 'dbo' as a default schema
public static final String MSSQL_DEFAULT_SCHEMA = "mssql.default.schema";

private static final Logger LOG = Logger.getLogger(MssqlEnvironmentHandler.class);
private static final String HEX_PREFIX_STR = "0x";
private static final Logger LOG = Logger.getLogger(MssqlEnvironmentHandler.class);
private static final String HEX_PREFIX_STR = "0x";
private String defaultSchema = null;

MssqlEnvironmentHandler( DbConnSQLServer dbConnection,
MssqlDbProvider dbProvider ) {

super(dbConnection, dbProvider);

defaultSchema = getDefaultSchema();
}

@Override
Expand All @@ -77,7 +76,7 @@ protected List<ColumnDescription> getColumnsToSelect(
ColumnHasNoDefaultValueException {

String fullTableName = table.getFullTableName();

String selectColumnsInfo = "SELECT COLUMN_NAME, DATA_TYPE, COLUMN_DEFAULT, CHARACTER_MAXIMUM_LENGTH, IS_NULLABLE, "
+ "columnproperty(object_id('"
+ fullTableName
Expand Down Expand Up @@ -140,7 +139,7 @@ protected void writeTableToFile(
+ AtsSystemProperties.SYSTEM_LINE_SEPARATOR);
}

if (this.dropEntireTable) {
if (shouldDropTable(table)) {
fileWriter.write(DROP_TABLE_MARKER + fullTableName
+ AtsSystemProperties.SYSTEM_LINE_SEPARATOR);
} else if (!this.deleteStatementsInserted) {
Expand Down Expand Up @@ -231,6 +230,9 @@ protected void writeDeleteStatements( Writer fileWriter ) throws IOException {
if (this.includeDeleteStatements) {
for (Entry<String, DbTable> entry : dbTables.entrySet()) {
DbTable dbTable = entry.getValue();
if (shouldDropTable(dbTable)) {
continue;
}
String fullTableName = null;
if (dbTable != null) {
fullTableName = dbTable.getFullTableName();
Expand Down Expand Up @@ -289,33 +291,17 @@ private StringBuilder extractValue(
}

@Override
public void createBackup( String backupFileName ) throws DatabaseEnvironmentCleanupException {

String defaultSchema = null;
try {
// get the default schema provided by the user
defaultSchema = CommonConfigurator.getInstance().getProperty(MSSQL_DEFAULT_SCHEMA);
if (StringUtils.isNullOrEmpty(defaultSchema)) {
// user had provided an empty string. Consider this an configuration error and use default mssql schema value (dbo) instead
LOG.warn("Provided '" + MSSQL_DEFAULT_SCHEMA
+ "' property has empty value. We will use 'dbo' as a default one instead");
defaultSchema = "dbo";
}
} catch (NoSuchPropertyException nspe) {
// no user provided default schema found. Fall back to dbo
defaultSchema = "dbo";
}
public void addTable( DbTable table ) {

// apply that schema to each table that has no schema specified
for (DbTable dbTable : dbTables.values()) {
if (dbTable != null) { // prevent NPE
if (StringUtils.isNullOrEmpty(dbTable.getTableSchema())) { // check if the table DOES NOT have schema already specified
dbTable.setTableSchema(defaultSchema);
if (!StringUtils.isNullOrEmpty(defaultSchema)) {
// apply that schema to each table that has no schema specified
if (table != null) { // prevent NPE
if (StringUtils.isNullOrEmpty(table.getTableSchema())) { // check if the table DOES NOT have schema already specified
table.setTableSchema(defaultSchema);
}
}
}

super.createBackup(backupFileName);
super.addTable(table);
}

/**
Expand Down Expand Up @@ -410,6 +396,33 @@ public void restore(
}
}

/**
* <p>Get the default schema for the current user and database.</p>
* */
private String getDefaultSchema() {

// get user's default schema
String query = "SELECT default_schema_name FROM sys.database_principals WHERE type = 'S' and name = '"
+ dbProvider.getDbConnection().getUser() + "'";
DbRecordValuesList[] defaultSchemaVal = dbProvider.select(new DbQuery(query),
DbReturnModes.ESCAPED_STRING);
if (defaultSchemaVal.length > 0) {
DbRecordValuesList firstVal = defaultSchemaVal[0];
if (firstVal != null) {
String defaultSchema = (String) firstVal.get("default_schema_name");
if (!StringUtils.isNullOrEmpty(defaultSchema)) {
LOG.info("Set default schema to '" + defaultSchema
+ "'. Tables that do not have schema specified will be assigned to that schema."
+ " Tables that do have provided schema will not be affected by that.");
return defaultSchema;
}
}
}

return null;

}

private void dropAndRecreateTable( Connection connection, String tableName ) {

List<String> generateForeignKeysScripts = new ArrayList<String>();
Expand Down
Expand Up @@ -212,10 +212,12 @@ protected void writeTableToFile(
DbTable table,
DbRecordValuesList[] records,
Writer fileWriter ) throws IOException {

if (this.dropEntireTable) {

boolean writeDeleteStatementForCurrTable = true;
if (shouldDropTable(table)) {
fileWriter.write(DROP_TABLE_MARKER + table.getTableSchema() + "." + table.getTableName()
+ AtsSystemProperties.SYSTEM_LINE_SEPARATOR);
writeDeleteStatementForCurrTable = false;
} /*else if (!this.deleteStatementsInserted) {
writeDeleteStatements(fileWriter);
}*/
Expand All @@ -227,7 +229,7 @@ protected void writeTableToFile(
fileWriter.write("LOCK TABLES `" + table.getTableName() + "` WRITE;" + EOL_MARKER
+ AtsSystemProperties.SYSTEM_LINE_SEPARATOR);
}
if (this.includeDeleteStatements) {
if (this.includeDeleteStatements && writeDeleteStatementForCurrTable) {
fileWriter.write("DELETE FROM `" + table.getTableName() + "`;" + EOL_MARKER
+ AtsSystemProperties.SYSTEM_LINE_SEPARATOR);
}
Expand Down

0 comments on commit 348b80c

Please sign in to comment.