use of liquibase.structure.DatabaseObject in project liquibase by liquibase.
the class SnapshotGeneratorFactory method has.
/**
* Checks if a specific object is present in a database
* @param example The DatabaseObject to check for existence
* @param database The DBMS in which the object might exist
* @return true if object existence can be confirmed, false otherweise
* @throws DatabaseException If a problem occurs in the DBMS-specific code
* @throws InvalidExampleException If the object cannot be checked properly, e.g. if the object name is ambiguous
*/
public boolean has(DatabaseObject example, Database database) throws DatabaseException, InvalidExampleException {
// @todo I have seen duplicates in types - maybe convert the List into a Set? Need to understand it more thoroughly.
List<Class<? extends DatabaseObject>> types = new ArrayList<>(getContainerTypes(example.getClass(), database));
types.add(example.getClass());
// @todo Actually, there may be extreme cases (distorted table statistics etc.) where a COUNT(*) might not be so cheap. Maybe SELECT a dummy constant is the better way?
if ((example instanceof Table) && (example.getName().equals(database.getDatabaseChangeLogTableName()) || example.getName().equals(database.getDatabaseChangeLogLockTableName()))) {
try {
Scope.getCurrentScope().getSingleton(ExecutorService.class).getExecutor("jdbc", database).queryForInt(new RawSqlStatement("SELECT COUNT(*) FROM " + database.escapeObjectName(database.getLiquibaseCatalogName(), database.getLiquibaseSchemaName(), example.getName(), Table.class)));
return true;
} catch (DatabaseException e) {
if (database instanceof PostgresDatabase) {
// throws "current transaction is aborted" unless we roll back the connection
database.rollback();
}
return false;
}
}
/*
* If the query is about another object, try to create a snapshot of the of the object (or used the cached
* snapshot. If that works, we count that as confirmation of existence.
*/
SnapshotControl snapshotControl = (new SnapshotControl(database, false, types.toArray(new Class[types.size()])));
snapshotControl.setWarnIfObjectNotFound(false);
if (createSnapshot(example, database, snapshotControl) != null) {
return true;
}
CatalogAndSchema catalogAndSchema;
if (example.getSchema() == null) {
catalogAndSchema = database.getDefaultSchema();
} else {
catalogAndSchema = example.getSchema().toCatalogAndSchema();
}
DatabaseSnapshot snapshot = createSnapshot(catalogAndSchema, database, new SnapshotControl(database, false, example.getClass()).setWarnIfObjectNotFound(false));
for (DatabaseObject obj : snapshot.get(example.getClass())) {
if (DatabaseObjectComparatorFactory.getInstance().isSameObject(example, obj, null, database)) {
return true;
}
}
return false;
}
use of liquibase.structure.DatabaseObject in project liquibase by liquibase.
the class SqlGeneratorFactory method getAffectedDatabaseObjects.
public Set<DatabaseObject> getAffectedDatabaseObjects(SqlStatement statement, Database database) {
Set<DatabaseObject> affectedObjects = new HashSet<>();
SqlGeneratorChain sqlGeneratorChain = createGeneratorChain(statement, database);
if (sqlGeneratorChain != null) {
// noinspection unchecked
Sql[] sqls = sqlGeneratorChain.generateSql(statement, database);
if (sqls != null) {
for (Sql sql : sqls) {
affectedObjects.addAll(sql.getAffectedDatabaseObjects());
}
}
}
return affectedObjects;
}
use of liquibase.structure.DatabaseObject in project liquibase by liquibase.
the class DatabaseSnapshot method init.
protected void init(DatabaseObject[] examples) throws DatabaseException, InvalidExampleException {
if (examples != null) {
Set<Catalog> catalogs = new HashSet<>();
for (DatabaseObject object : examples) {
if (object instanceof Schema) {
catalogs.add(((Schema) object).getCatalog());
}
}
this.setScratchData("DatabaseSnapshot.allCatalogs", catalogs);
if (catalogs.size() > 1) {
List<String> quotedCatalogs = new ArrayList<String>();
for (Catalog catalog : catalogs) {
quotedCatalogs.add("'" + catalog.getName() + "'");
}
if (CatalogAndSchema.CatalogAndSchemaCase.ORIGINAL_CASE.equals(database.getSchemaAndCatalogCase())) {
this.setScratchData(ALL_CATALOGS_STRING_SCRATCH_KEY, StringUtil.join(quotedCatalogs, ", "));
} else {
this.setScratchData(ALL_CATALOGS_STRING_SCRATCH_KEY, StringUtil.join(quotedCatalogs, ", ").toUpperCase());
}
}
if (getDatabase().supportsCatalogs()) {
for (Catalog catalog : catalogs) {
this.snapshotControl.addType(catalog.getClass(), database);
include(catalog);
}
}
for (DatabaseObject obj : examples) {
this.snapshotControl.addType(obj.getClass(), database);
include(obj);
}
}
}
use of liquibase.structure.DatabaseObject in project liquibase by liquibase.
the class DatabaseSnapshot method merge.
/**
* Method which merges two object snapshot models into one
*
* @param snapshotToMerge Another object snapshot model
* @return DatabaseSnapshot Merged object model
*/
public DatabaseSnapshot merge(DatabaseSnapshot snapshotToMerge) {
DatabaseSnapshot returnSnapshot = this;
Map<Class<? extends DatabaseObject>, Set<? extends DatabaseObject>> allFoundMap = snapshotToMerge.allFound.toMap();
Map<Class<? extends DatabaseObject>, Set<? extends DatabaseObject>> referencedObjectsMap = snapshotToMerge.referencedObjects.toMap();
for (Set<? extends DatabaseObject> setOfDatabaseObject : allFoundMap.values()) {
for (DatabaseObject dbObject : setOfDatabaseObject) {
returnSnapshot.allFound.add(dbObject);
}
}
for (Set<? extends DatabaseObject> setOfDatabaseObject : referencedObjectsMap.values()) {
for (DatabaseObject dbObject : setOfDatabaseObject) {
returnSnapshot.referencedObjects.add(dbObject);
}
}
return returnSnapshot;
}
use of liquibase.structure.DatabaseObject in project liquibase by liquibase.
the class DBDocVisitor method visit.
@Override
public void visit(ChangeSet changeSet, DatabaseChangeLog databaseChangeLog, Database database, Set<ChangeSetFilterResult> filterResults) throws LiquibaseException {
ChangeSet.RunStatus runStatus = this.database.getRunStatus(changeSet);
if (rootChangeLogName == null) {
rootChangeLogName = changeSet.getFilePath();
}
if (rootChangeLog == null) {
this.rootChangeLog = databaseChangeLog;
}
if (!changesByAuthor.containsKey(changeSet.getAuthor())) {
changesByAuthor.put(changeSet.getAuthor(), new ArrayList<Change>());
}
if (!changesToRunByAuthor.containsKey(changeSet.getAuthor())) {
changesToRunByAuthor.put(changeSet.getAuthor(), new ArrayList<Change>());
}
boolean toRun = runStatus.equals(ChangeSet.RunStatus.NOT_RAN) || runStatus.equals(ChangeSet.RunStatus.RUN_AGAIN);
for (Change change : changeSet.getChanges()) {
if (toRun) {
changesToRunByAuthor.get(changeSet.getAuthor()).add(change);
changesToRun.add(change);
} else {
changesByAuthor.get(changeSet.getAuthor()).add(change);
recentChanges.add(0, change);
}
}
ChangeLogInfo changeLogInfo = new ChangeLogInfo(changeSet.getChangeLog().getLogicalFilePath(), changeSet.getChangeLog().getPhysicalFilePath());
if (!changeLogs.contains(changeLogInfo)) {
changeLogs.add(changeLogInfo);
}
for (Change change : changeSet.getChanges()) {
Set<DatabaseObject> affectedDatabaseObjects = change.getAffectedDatabaseObjects(database);
if (affectedDatabaseObjects != null) {
for (DatabaseObject dbObject : affectedDatabaseObjects) {
if (toRun) {
if (!changesToRunByObject.containsKey(dbObject)) {
changesToRunByObject.put(dbObject, new ArrayList<Change>());
}
changesToRunByObject.get(dbObject).add(change);
} else {
if (!changesByObject.containsKey(dbObject)) {
changesByObject.put(dbObject, new ArrayList<Change>());
}
changesByObject.get(dbObject).add(change);
}
}
}
}
}
Aggregations