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 ( ) ) ; /* * Does the query concern the DATABASECHANGELOG / DATABASECHANGELOGLOCK table? If so, we do a quick & dirty * SELECT COUNT(*) on that table. If that works, we count that as confirmation of existence. */ // @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 { ExecutorService . getInstance ( ) . getExecutor ( 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 ; }
Checks if a specific object is present in a database