Search in sources :

Example 1 with TableDescription

use of com.axway.ats.common.dbaccess.snapshot.TableDescription in project ats-framework by Axway.

the class DatabaseSnapshot method compareTables.

/**
     * Compares all tables between two snapshots
     * 
     * @param thisSnapshotName
     * @param thisTables
     * @param thatSnapshotName
     * @param thatTables
     * @param thatDbProvider
     * @param allTablesToSkip
     * @param allSkipRules
     * @param indexNameMatcher
     * @param thatBackupXmlFile
     * @param equality
     */
private void compareTables(String thisSnapshotName, List<TableDescription> thisTables, String thatSnapshotName, List<TableDescription> thatTables, DbProvider thatDbProvider, Set<String> allTablesToSkip, Map<String, SkipRules> allSkipRules, Set<String> allTablesContentSkip, Map<String, Map<String, String>> allRowsToSkip, IndexNameMatcher indexNameMatcher, Document thatBackupXmlFile, EqualityState equality) {
    // make a list of tables present in both snapshots
    List<String> commonTables = getCommonTables(thisSnapshotName, thisTables, thatSnapshotName, thatTables, allTablesToSkip);
    for (String tableName : commonTables) {
        // get tables to compare
        TableDescription thisTable = null;
        TableDescription thatTable = null;
        for (TableDescription table : thisTables) {
            if (table.getName().equalsIgnoreCase(tableName)) {
                thisTable = table;
                break;
            }
        }
        for (TableDescription table : thatTables) {
            if (table.getName().equalsIgnoreCase(tableName)) {
                thatTable = table;
                break;
            }
        }
        SkipRules tableSkipRules = allSkipRules.get(thisTable.getName());
        if (tableSkipRules != null && tableSkipRules.isSkipWholeTable()) {
            // if table is not of interest - skip it
            continue;
        }
        List<String> thisValuesList = null;
        List<String> thatValuesList = null;
        if (!allTablesContentSkip.contains(tableName.toLowerCase())) {
            // load the content of this snapshot's table
            thisValuesList = loadTableData(thisSnapshotName, thisTable, allSkipRules, allRowsToSkip, this.dbProvider, backupXmlFile);
            // load the content of that snapshot's table
            thatValuesList = loadTableData(thatSnapshotName, thatTable, allSkipRules, allRowsToSkip, thatDbProvider, thatBackupXmlFile);
        }
        thisTable.compare(thatTable, thisValuesList, thatValuesList, indexNameMatcher, equality);
    }
    thisTables.clear();
}
Also used : TableDescription(com.axway.ats.common.dbaccess.snapshot.TableDescription)

Example 2 with TableDescription

use of com.axway.ats.common.dbaccess.snapshot.TableDescription in project ats-framework by Axway.

the class AbstractDbProvider method getTableDescriptions.

/**
     * @return description about all tables present in the database
     */
@Override
public List<TableDescription> getTableDescriptions() {
    ResultSet tablesResultSet = null;
    List<TableDescription> tables = new ArrayList<TableDescription>();
    try (Connection connection = ConnectionPool.getConnection(dbConnection)) {
        DatabaseMetaData databaseMetaData = connection.getMetaData();
        tablesResultSet = databaseMetaData.getTables(null, null, null, new String[] { "TABLE" });
        while (tablesResultSet.next()) {
            if (this instanceof OracleDbProvider && !tablesResultSet.getString(2).equalsIgnoreCase(dbConnection.user)) {
                // Oracle gives us all tables from all databases, we filter here only ours
                continue;
            }
            String tableName = tablesResultSet.getString("TABLE_NAME");
            if (!isTableAccepted(tablesResultSet, dbConnection.db, tableName)) {
                // Table is skipped
                continue;
            }
            log.debug("Extracting description about '" + tableName + "' table");
            TableDescription table = new TableDescription();
            table.setName(tableName);
            table.setSchema(tablesResultSet.getString("TABLE_SCHEM"));
            table.setPrimaryKeyColumn(exctractPrimaryKeyColumn(tableName, databaseMetaData));
            table.setIndexes(extractTableIndexes(tableName, databaseMetaData, connection.getCatalog()));
            List<String> columnDescriptions = new ArrayList<>();
            extractTableColumns(tableName, databaseMetaData, columnDescriptions);
            table.setColumnDescriptions(columnDescriptions);
            tables.add(table);
        }
    } catch (SQLException sqle) {
        throw new DbException("Error extracting DB schema information", sqle);
    } finally {
        if (tablesResultSet != null) {
            try {
                tablesResultSet.close();
            } catch (SQLException e) {
                log.warn("Result set resouce could not be closed!", e);
            }
        }
    }
    return tables;
}
Also used : OracleDbProvider(com.axway.ats.core.dbaccess.oracle.OracleDbProvider) SQLException(java.sql.SQLException) ResultSet(java.sql.ResultSet) ArrayList(java.util.ArrayList) Connection(java.sql.Connection) DatabaseMetaData(java.sql.DatabaseMetaData) TableDescription(com.axway.ats.common.dbaccess.snapshot.TableDescription) DbException(com.axway.ats.core.dbaccess.exceptions.DbException)

Example 3 with TableDescription

use of com.axway.ats.common.dbaccess.snapshot.TableDescription in project ats-framework by Axway.

the class DatabaseSnapshot method compare.

/**
 * Compare both snapshots and throw error if unexpected differences are found.
 * Snapshots are compared table by table.
 * In the usual case the tables are loaded from database prior to comparing.
 * But if a snapshot was saved into a file, then its tables are loaded from the file, not from the database.
 *
 * @param that the snapshot to compare to
 * @param compareOptions - (optional) additional options that change the comparison. by default is null, so the compare is as-is (e.g. if there is an error, the comparison fails)
 * @throws DatabaseSnapshotException
 */
@PublicAtsApi
public void compare(DatabaseSnapshot that, CompareOptions compareOptions) throws DatabaseSnapshotException {
    try {
        if (that == null) {
            throw new DatabaseSnapshotException("Snapshot to compare is null");
        }
        if (this.name.equals(that.name)) {
            throw new DatabaseSnapshotException("You are trying to compare snapshots with same name: " + this.name);
        }
        if (this.metadataTimestamp == -1) {
            throw new DatabaseSnapshotException("You are trying to compare snapshots but [" + this.name + "] snapshot is still not created");
        }
        if (that.metadataTimestamp == -1) {
            throw new DatabaseSnapshotException("You are trying to compare snapshots but [" + that.name + "] snapshot is still not created");
        }
        if (log.isDebugEnabled()) {
            log.debug("Comparing snapshots [" + this.name + "] taken on " + DatabaseSnapshotUtils.dateToString(this.metadataTimestamp) + " and [" + that.name + "] taken on " + DatabaseSnapshotUtils.dateToString(that.metadataTimestamp));
        }
        this.equality = new DatabaseEqualityState(this.name, that.name);
        // make copies of the table info, as we will remove from these lists,
        // but we do not want to remove from the original table info lists
        List<TableDescription> thisTables = new ArrayList<TableDescription>(this.tables);
        List<TableDescription> thatTables = new ArrayList<TableDescription>(that.tables);
        // Merge all skip rules from both snapshot instances,
        // so it is not needed to add same skip rules in both snapshot instances.
        // merge all columns to be skipped(per table)
        Map<String, SkipColumns> skipColumns = mergeSkipColumns(that.skipColumnsPerTable);
        // merge all content to be skipper(per table)
        Map<String, SkipContent> skipContent = mergeSkipContent(that.skipContentPerTable);
        // merge all rows to be skipped(per table)
        Map<String, SkipRows> skipRows = mergeSkipRows(that.skipRowsPerTable);
        Set<String> tablesToSkip = getAllTablesToSkip(skipColumns);
        // We can use just one index name matcher
        IndexMatcher actualIndexNameMatcher = mergeIndexMatchers(that.indexMatcher);
        compareTables(this.name, thisTables, that.name, thatTables, that.dbProvider, tablesToSkip, skipColumns, skipContent, skipRows, actualIndexNameMatcher, that.backupXmlFile, equality);
        if (compareOptions != null) {
            try {
                // handle expected differences
                handleExpectedMissingRows(compareOptions, equality);
            } catch (Exception e) {
                log.error("Error occured while handling missing rows", e);
            }
        }
        if (equality.hasDifferences()) {
            // there are some unexpected differences
            throw new DatabaseSnapshotException(equality);
        } else {
            log.info("Successful verification");
        }
    } finally {
        // close the database connections
        disconnect(this.dbProvider, "after comparing database snapshots");
        disconnect(that.dbProvider, "after comparing database snapshots");
    }
}
Also used : IndexMatcher(com.axway.ats.common.dbaccess.snapshot.IndexMatcher) SkipRows(com.axway.ats.action.dbaccess.snapshot.rules.SkipRows) SkipContent(com.axway.ats.action.dbaccess.snapshot.rules.SkipContent) ArrayList(java.util.ArrayList) TableDescription(com.axway.ats.common.dbaccess.snapshot.TableDescription) DatabaseSnapshotException(com.axway.ats.common.dbaccess.snapshot.DatabaseSnapshotException) DatabaseEqualityState(com.axway.ats.common.dbaccess.snapshot.equality.DatabaseEqualityState) DatabaseSnapshotException(com.axway.ats.common.dbaccess.snapshot.DatabaseSnapshotException) SkipColumns(com.axway.ats.action.dbaccess.snapshot.rules.SkipColumns) PublicAtsApi(com.axway.ats.common.PublicAtsApi)

Example 4 with TableDescription

use of com.axway.ats.common.dbaccess.snapshot.TableDescription in project ats-framework by Axway.

the class DatabaseSnapshot method getCommonTables.

private List<String> getCommonTables(String thisSnapshotName, List<TableDescription> thisTables, String thatSnapshotName, List<TableDescription> thatTables, Set<String> tablesToSkip) {
    // list of names of tables present in both snapshots
    List<String> commonTables = new ArrayList<String>();
    // check if all tables from THIS snapshot are present in the THAT one
    for (TableDescription thisTable : thisTables) {
        // do not deal with tables that are to be skipped
        if (!tablesToSkip.contains(thisTable.getName())) {
            boolean tablePresentInBothSnapshots = false;
            for (TableDescription thatTable : thatTables) {
                if (thatTable.getName().equalsIgnoreCase(thisTable.getName())) {
                    commonTables.add(thisTable.getName());
                    tablePresentInBothSnapshots = true;
                    break;
                }
            }
            if (!tablePresentInBothSnapshots) {
                equality.addTablePresentInOneSnapshotOnly(thisSnapshotName, thisTable.getName());
            }
        }
    }
    // check if all tables from THAT snapshot are present in the THIS one
    for (TableDescription thatTable : thatTables) {
        // do not deal with tables that are to be skipped
        if (!tablesToSkip.contains(thatTable.getName())) {
            boolean tablePresentInBothSnapshots = false;
            for (TableDescription thisTable : thisTables) {
                if (thisTable.getName().equalsIgnoreCase(thatTable.getName())) {
                    tablePresentInBothSnapshots = true;
                    break;
                }
            }
            if (!tablePresentInBothSnapshots) {
                equality.addTablePresentInOneSnapshotOnly(thatSnapshotName, thatTable.getName());
            }
        }
    }
    return commonTables;
}
Also used : ArrayList(java.util.ArrayList) TableDescription(com.axway.ats.common.dbaccess.snapshot.TableDescription)

Example 5 with TableDescription

use of com.axway.ats.common.dbaccess.snapshot.TableDescription in project ats-framework by Axway.

the class DatabaseSnapshot method takeSnapshot.

/**
 * Take a database snapshot<br>
 * <b>NOTE:</b> We will get only meta data about the tables in the database.
 * No table content is loaded at this moment as this may cause memory issues.
 * The content of each table is loaded when needed while comparing this snapshot with another one, or while
 * saving the snapshot into a file.
 */
@PublicAtsApi
public void takeSnapshot() {
    this.metadataTimestamp = System.currentTimeMillis();
    dbProvider = DatabaseProviderFactory.getDatabaseProvider(testBox.getDbType(), testBox.getHost(), testBox.getDbName(), testBox.getDbUser(), testBox.getDbPass(), testBox.getDbPort(), customProperties);
    log.info("Start taking database meta information for snapshot [" + name + "] from " + dbProvider.getDbConnection().getDescription());
    // load info about all present tables
    tables = dbProvider.getTableDescriptions(getSkippedTables());
    if (tables.size() == 0) {
        log.warn("No tables found for snapshot [" + name + "]");
    }
    // remove the tables that are to be skipped
    for (String tableToSkip : getAllTablesToSkip(skipColumnsPerTable)) {
        for (TableDescription table : tables) {
            if (table.getName().equalsIgnoreCase(tableToSkip)) {
                tables.remove(table);
                break;
            }
        }
    }
    // remove indexes that are to be skipped
    skipIndexes();
    // we have loaded all index info, strip some if needed
    stripIndexAttributes(tables);
    for (TableDescription table : tables) {
        table.setSnapshotName(this.name);
    }
    // in case we have made a backup file, now it is time to forget about it
    this.backupXmlFile = null;
    log.info("End taking database meta information for snapshot with name " + name);
}
Also used : TableDescription(com.axway.ats.common.dbaccess.snapshot.TableDescription) PublicAtsApi(com.axway.ats.common.PublicAtsApi)

Aggregations

TableDescription (com.axway.ats.common.dbaccess.snapshot.TableDescription)11 ArrayList (java.util.ArrayList)5 DatabaseSnapshotException (com.axway.ats.common.dbaccess.snapshot.DatabaseSnapshotException)4 SkipColumns (com.axway.ats.action.dbaccess.snapshot.rules.SkipColumns)3 SkipContent (com.axway.ats.action.dbaccess.snapshot.rules.SkipContent)3 PublicAtsApi (com.axway.ats.common.PublicAtsApi)3 SkipIndexAttributes (com.axway.ats.action.dbaccess.snapshot.rules.SkipIndexAttributes)2 SkipRows (com.axway.ats.action.dbaccess.snapshot.rules.SkipRows)2 DbException (com.axway.ats.core.dbaccess.exceptions.DbException)2 OracleDbProvider (com.axway.ats.core.dbaccess.oracle.OracleDbProvider)2 Connection (java.sql.Connection)2 DatabaseMetaData (java.sql.DatabaseMetaData)2 ResultSet (java.sql.ResultSet)2 SQLException (java.sql.SQLException)2 HashMap (java.util.HashMap)2 IndexMatcher (com.axway.ats.common.dbaccess.snapshot.IndexMatcher)1 IndexNameMatcher (com.axway.ats.common.dbaccess.snapshot.IndexNameMatcher)1 DatabaseEqualityState (com.axway.ats.common.dbaccess.snapshot.equality.DatabaseEqualityState)1 EqualityState (com.axway.ats.common.dbaccess.snapshot.equality.EqualityState)1 MariaDbDbProvider (com.axway.ats.core.dbaccess.mariadb.MariaDbDbProvider)1