Hi,
In the old sql script we had a validation ( just check if there is any invalid object in the database ), and after the validation if there is any invalid object we were printing the result with the ones that are invalid. This was really useful when you are running the script.
I partially fixed the problem using a precondition, and if there is any invalid object i just finish the execution of the script and i print the error message. But I would like to list the invalid objects also. Any Idea or suggestion ??
Current code:
-
<preConditions onFailMessage=“There are invalid objects in the database!!”
onFail=“HALT” >
<![CDATA[
SELECT count(1)
FROM all_objects alo
WHERE status = ‘INVALID’
AND alo.owner in
(‘CIN’,‘NOPA’,‘ORC’,‘PRV’,‘SEC’,‘TIPI_OWNER’,‘TT’,‘ZON’);
]]>
<![CDATA[
SELECT alo.owner
, alo.object_name
, alo.status
, alo.last_ddl_time
FROM all_objects alo
WHERE status = ‘INVALID’
AND alo.owner in
(‘CIN’,‘NOPA’,‘ORC’,‘PRV’,‘SEC’,‘TIPI_OWNER’,‘TT’,‘ZON’);
]]>
Thanks in advance
To get the problem object in the output message, you’ll probably need to write a custom precondition class. There is documentation on it at http://www.liquibase.org/documentation/preconditions.html
Within a custom precondition, you have whatever flexibility you need both in what you are checking and the output.
Nathan
Thanks for your reply Nathan!
I’m trying to make it work, and looks good so far, but I would like to enable the logger, then will be easy to see what i’m doing. But I don’t know why I can’t see the log in debug level.
This is my code:
-
-
- <preConditions onFailMessage="There are invalid objects in the database!!"
-
onFail=“HALT”>
-
<customPrecondition
-
className=“nl.tele2.bos.liquibase.custom.preconditions.CustomBuildCheck”>
- <param name=“sql”
- value="SELECT count(1)
- FROM all_objects alo
- WHERE status = ‘INVALID’
- AND alo.owner in
-
(‘BOS_RELEASE’,‘BIL’,‘BLIS’,‘CBSMIG’,‘COJO’,‘CMD_AGENT’,‘CIN’,‘NOPA’,‘ORC’,‘PRV’,‘SEC’,‘TIPI_OWNER’,‘TT’,‘ZON’)
- AND alo.OBJECT_NAME not like ‘TST%’
- AND alo.OBJECT_NAME not like ‘TEST%’
- AND ALO.OBJECT_NAME <> ‘ZON_ORBIT_LOG_PCK’
- AND ALO.OBJECT_NAME <> ‘ZON_TESTING_PCK’
- AND ALO.OBJECT_NAME <> ‘ZON_MONITORING_PCK’;"/>
- <param name=“sqlNames” value="SELECT alo.owner
- , alo.object_name
- , alo.status
-
,
-
alo.last_ddl_time
- FROM all_objects alo
- WHERE status = ‘INVALID’
-
AND
- alo.owner in
-
(‘BOS_RELEASE’,‘BIL’,‘BLIS’,‘CBSMIG’,‘COJO’,‘CMD_AGENT’,‘CIN’,‘NOPA’,‘ORC’,‘PRV’,‘SEC’,‘TIPI_OWNER’,‘TT’,‘ZON’)
- AND alo.OBJECT_NAME not like ‘TST%’
- AND alo.OBJECT_NAME not like
-
‘TEST%’
- AND ALO.OBJECT_NAME <> ‘ZON_ORBIT_LOG_PCK’
-
AND
- ALO.OBJECT_NAME <> ‘ZON_TESTING_PCK’
- AND ALO.OBJECT_NAME <>
-
‘ZON_MONITORING_PCK’
- ORDER BY alo.owner, alo.object_name;"/>
-
-
-
-
Java class:
-
- import liquibase.database.Database;
- import liquibase.database.DatabaseConnection;
- import liquibase.exception.CustomPreconditionErrorException;
- import liquibase.exception.CustomPreconditionFailedException;
- import liquibase.exception.DatabaseException;
- import liquibase.executor.ExecutorService;
- import liquibase.logging.LogFactory;
- import liquibase.logging.Logger;
- import liquibase.precondition.CustomPrecondition;
- import liquibase.statement.core.RawSqlStatement;
- import lombok.Getter;
- import lombok.Setter;
-
- /**
- * CustomBuildCheck Precondition
- *
- *
- *
- *
- *
- *
- * @author Enric Ballo
- * @since Oct 24, 2014
- */
- public class CustomBuildCheck implements CustomPrecondition {
-
- private final Logger logger = LogFactory.getInstance().getLog("CustomBuildCheck");
-
- @Getter
- @Setter
- private String expectedResult;
-
- @Getter
- @Setter
- private String sql;
-
- @Getter
- @Setter
- private String sqlNames;
-
- @Override
- public void check(final Database database) throws CustomPreconditionFailedException, CustomPreconditionErrorException {
-
- final DatabaseConnection connection = database.getConnection();
- try {
- logger.debug("CustomBuildCheck is executed...");
-
- final String result =
- ExecutorService.getInstance().getExecutor(database).queryForObject(
- new RawSqlStatement(getSql().replaceFirst(";$", "")), String.class);
-
- if (result == null) {
- throw new CustomPreconditionFailedException("No rows returned from SQL Precondition");
- }
-
- logger.debug("result is :"+result);
-
- if (!expectedResult.equals(result)) {
-
- logger.debug("We have some errors! ");
-
- // final String resultNames = ExecutorService.getInstance().getExecutor(database).queryForObject(new RawSqlStatement(getSqlNames().replaceFirst(";$", "")), String.class);
-
- throw new CustomPreconditionFailedException("SQL Precondition failed. Expected '" + expectedResult + "' got '" + result
- + "'");
- }
-
- } catch (final DatabaseException e) {
- throw new CustomPreconditionFailedException(e.getMessage());
- }
- }
-
- }
Result in the console:
-
- DEBUG 10/27/14 3:27 PM: liquibase: liquibase/changelogs/bos-incremental-changelog.xml: liquibase/changelogs/bos-incremental-databaseCheck-changelog.xml::dataBaseCheck_v2::e-ballo: Computed checksum for as d41d8cd98f00b204e9800998ecf8427e
- DEBUG 10/27/14 3:27 PM: liquibase: liquibase/changelogs/bos-incremental-changelog.xml: liquibase/changelogs/bos-incremental-databaseCheck-changelog.xml::dataBaseCheck_v2::e-ballo: Running Changeset:liquibase/changelogs/bos-incremental-databaseCheck-changelog.xml::dataBaseCheck_v2::e-ballo
- DEBUG 10/27/14 3:27 PM: liquibase: liquibase/changelogs/bos-incremental-changelog.xml: liquibase/changelogs/bos-incremental-databaseCheck-changelog.xml::dataBaseCheck_v2::e-ballo: Changeset liquibase/changelogs/bos-incremental-databaseCheck-changelog.xml::dataBaseCheck_v2::e-ballo
- DEBUG 10/27/14 3:27 PM: liquibase: liquibase/changelogs/bos-incremental-changelog.xml: liquibase/changelogs/bos-incremental-databaseCheck-changelog.xml::dataBaseCheck_v2::e-ballo: Executing QUERY database command: SELECT count(1) FROM all_objects alo WHERE status = 'INVALID' AND alo.owner in ('BOS_RELEASE','BIL','BLIS','CBSMIG','COJO','CMD_AGENT','CIN','NOPA','ORC','PRV','SEC','TIPI_OWNER','TT','ZON') AND alo.OBJECT_NAME not like 'TST%' AND alo.OBJECT_NAME not like 'TEST%' AND ALO.OBJECT_NAME <> 'ZON_ORBIT_LOG_PCK' AND ALO.OBJECT_NAME <> 'ZON_TESTING_PCK' AND ALO.OBJECT_NAME <> 'ZON_MONITORING_PCK'
- SEVERE 10/27/14 3:27 PM: liquibase: liquibase/changelogs/bos-incremental-changelog.xml: liquibase/changelogs/bos-incremental-databaseCheck-changelog.xml::dataBaseCheck_v2::e-ballo: Change Set liquibase/changelogs/bos-incremental-databaseCheck-changelog.xml::dataBaseCheck_v2::e-ballo failed. Error: Migration failed for change set liquibase/changelogs/bos-incremental-databaseCheck-changelog.xml::dataBaseCheck_v2::e-ballo:
- Reason:
- liquibase/changelogs/bos-incremental-changelog.xml : There are invalid objects in the database!!
-
- liquibase.exception.MigrationFailedException: Migration failed for change set liquibase/changelogs/bos-incremental-databaseCheck-changelog.xml::dataBaseCheck_v2::e-ballo:
- Reason:
- liquibase/changelogs/bos-incremental-changelog.xml : There are invalid objects in the database!!
-
- at liquibase.changelog.ChangeSet.execute(ChangeSet.java:463)
- at liquibase.changelog.visitor.UpdateVisitor.visit(UpdateVisitor.java:43)
- at liquibase.changelog.ChangeLogIterator.run(ChangeLogIterator.java:70)
- at liquibase.Liquibase.update(Liquibase.java:195)
- at liquibase.Liquibase.update(Liquibase.java:174)
- at liquibase.integration.commandline.Main.doMigration(Main.java:997)
- at liquibase.integration.commandline.Main.run(Main.java:170)
- at liquibase.integration.commandline.Main.main(Main.java:89)
- Caused by: liquibase.exception.PreconditionFailedException: Preconditions Failed
- at liquibase.precondition.core.PreconditionContainer.check(PreconditionContainer.java:220)
- at liquibase.changelog.ChangeSet.execute(ChangeSet.java:449)
- ... 7 more
- DEBUG 10/27/14 3:27 PM: liquibase: liquibase/changelogs/bos-incremental-databaseCheck-changelog.xml::dataBaseCheck_v2::e-ballo: Release Database Lock
- DEBUG 10/27/14 3:27 PM: liquibase: liquibase/changelogs/bos-incremental-databaseCheck-changelog.xml::dataBaseCheck_v2::e-ballo: Executing UPDATE database command: UPDATE BOS_RELEASE.DATABASECHANGELOGLOCK SET LOCKED = 0, LOCKEDBY = NULL, LOCKGRANTED = NULL WHERE ID = 1
- INFO 10/27/14 3:27 PM: liquibase: liquibase/changelogs/bos-incremental-databaseCheck-changelog.xml::dataBaseCheck_v2::e-ballo: Successfully released change log lock
- Unexpected error running Liquibase: Preconditions Failed
-
How shall i use the Logger ? do am I doing something wrong ?
Thanks in advance
Ok, I just fixed
Just if someone want to know the LogFactory should be like this:
- private final Logger logger = LogFactory.getInstance().getLog("liquibase");
Glad you got it figured out. Thanks for letting us know.
Nathan
The easiest way with JdbcExecutor to query is to use a queryForList() method. If you want to specify the exact SQL, use executor.queryForList(new RawSqlStatement(YOUR_SQL)
which will return a List of Maps containing the data from the result set.
Nathan
Great, thanks for sharing.
Nathan
I’m almost done, but i would like to know if there is a way to execute a query and get a list of results.
I was looking into JdbcExecutor class and i don’t have a clear idea how i can do that.
I would like to do this query when I have errors, and then display in the logs as a sever the list of all the object that are not working.
-
- SELECT alo.owner
- , alo.object_name
- , alo.status
- , alo.last_ddl_time
- FROM all_objects alo
- WHERE status = 'INVALID'
- AND alo.owner in
- ('BOS_RELEASE','BIL','BLIS','CBSMIG','COJO','CMD_AGENT','CIN','NOPA','ORC','PRV','SEC','TIPI_OWNER','TT','ZON')
- AND alo.OBJECT_NAME not like 'TST%'
- AND alo.OBJECT_NAME not like 'TEST%'
- AND ALO.OBJECT_NAME <> 'ZON_ORBIT_LOG_PCK'
- AND ALO.OBJECT_NAME <> 'ZON_TESTING_PCK'
- AND ALO.OBJECT_NAME <> 'ZON_MONITORING_PCK'
- ORDER BY alo.owner, alo.object_name;
Thanks in advance,
I already have a solution for that I would like to share with you guys, maybe is useful for someone.
Java Class
-
- /**
- * CustomBuildCheck Precondition
- *
- *
- *
- *
- *
- * @author Enric Ballo (enric.ballo@tele2.com)
- * @since Oct 24, 2014
- */
- @Getter
- @Setter
- public class CustomBuildCheck implements CustomPrecondition {
-
- private static final String LAST_DDL_TIME = "LAST_DDL_TIME";
-
- /** Liquibase logger */
- private final Logger logger = LogFactory.getInstance().getLog("liquibase");
-
- /** the sql to execute */
- private String sql;
-
- /** the expected result */
- private String expectedResult;
-
- @SuppressWarnings("rawtypes")
- @Override
- public void check(final Database database) throws CustomPreconditionFailedException, CustomPreconditionErrorException {
-
- try {
-
- logger.debug("CustomBuildCheck is executed...");
-
- final List<Map> resultQuery =
- ExecutorService.getInstance().getExecutor(database).queryForList(
- new RawSqlStatement(getSql().replaceFirst(";$", "")));
-
- if (resultQuery == null) {
- throw new CustomPreconditionFailedException("No rows returned from SQL Precondition");
- }
-
- final int size = resultQuery.size();
-
- logger.debug("result is :" + size);
- logger.debug("expected result is :" + expectedResult);
-
- final Integer resultInteger = new Integer(size);
- final Integer expectIntegerResult = new Integer(expectedResult);
-
- if (!expectIntegerResult.equals(resultInteger)) {
-
- logger.debug("We have some errors! displaying the result");
-
- final StringBuilder invalidObject = new StringBuilder();
-
- int counter = 1;
- for (final Map map : resultQuery) {
-
- invalidObject.append(" " + counter + " ) ");
-
- for (final Map.Entry entry : map.entrySet()) {
- invalidObject.append(entry.getValue());
-
- //Avoid the last -
- if (!entry.getKey().equals(LAST_DDL_TIME)) {
- invalidObject.append(" - ");
- }
-
- }
-
- invalidObject.append("\n");
- counter++;
- }
-
- final StringBuilder message = new StringBuilder();
- message.append("\n");
- message.append("\n");
- message.append("\n");
- message.append("--------------------------------------------------------------------------------------------- \n");
- message.append(" ERROR - There are " + size + " invalid Objects in the Database \n");
- message.append("--------------------------------------------------------------------------------------------- \n");
- message.append(" OWNER - OBJECT NAME - STATUS - LAST DDL TIME \n");
- message.append("\n");
- message.append(invalidObject.toString());
- message.append("\n");
- message.append("--------------------------------------------------------------------------------------------- \n");
- message.append("\n");
- message.append("\n");
-
- throw new CustomPreconditionFailedException(message.toString());
- }
-
- } catch (final DatabaseException e) {
- throw new CustomPreconditionFailedException(e.getMessage());
- }
- }
-
- }
ChangeLog file
-
-
-
-
<customPrecondition
-
className=“nl.tele2.bos.liquibase.custom.preconditions.CustomBuildCheck”>
- <param name=“sql” value="SELECT alo.owner
-
,alo.object_name
-
,alo.status
-
,alo.last_ddl_time
-
FROM all_objects alo
-
WHERE status = ‘INVALID’
-
AND alo.owner in (‘BOS_RELEASE’,‘BIL’,‘BLIS’,‘CBSMIG’,‘COJO’,‘CMD_AGENT’,‘CIN’,‘NOPA’,‘ORC’,‘PRV’,‘SEC’,‘TIPI_OWNER’,‘TT’,‘ZON’)
-
AND alo.OBJECT_NAME not like ‘TST%’
-
AND alo.OBJECT_NAME not like ‘TEST%’
-
AND ALO.OBJECT_NAME <> ‘ZON_ORBIT_LOG_PCK’
-
AND ALO.OBJECT_NAME <> ‘ZON_TESTING_PCK’
-
AND ALO.OBJECT_NAME <> ‘ZON_MONITORING_PCK’
-
ORDER BY alo.owner, alo.object_name;"/>
-
-
-
-
Sample output:
SEVERE 10/30/14 9:52 AM: liquibase: liquibase/changelogs/bos-incremental-changelog.xml: liquibase/changelogs/bos-incremental-databaseCheck-changelog.xml::dataBaseCheck_v2::e-ballo: Change Set liquibase/changelogs/bos-incremental-databaseCheck-changelog.xml::dataBaseCheck_v2::e-ballo failed. Error: Migration failed for change set liquibase/changelogs/bos-incremental-databaseCheck-changelog.xml::dataBaseCheck_v2::e-ballo:
Reason:
liquibase/changelogs/bos-incremental-changelog.xml : Custom Precondition Failed:
---------------------------------------------------------------------------------------------
ERROR - There are 1 invalid Objects in the Database
---------------------------------------------------------------------------------------------
OWNER - OBJECT NAME - STATUS - LAST DDL TIME
1 ) ZON - T2_ORDER_ENTRY_PCK - INVALID - 2014-10-30 09:52:36.0
---------------------------------------------------------------------------------------------