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();
}
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;
}
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");
}
}
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;
}
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);
}
Aggregations