diff --git a/orcas_core/build_source/orcas_diff/src/main/java/de/opitzconsulting/orcas/diff/ExecuteSqlErrorHandler.java b/orcas_core/build_source/orcas_diff/src/main/java/de/opitzconsulting/orcas/diff/ExecuteSqlErrorHandler.java index ccefaa4a..6ad73499 100644 --- a/orcas_core/build_source/orcas_diff/src/main/java/de/opitzconsulting/orcas/diff/ExecuteSqlErrorHandler.java +++ b/orcas_core/build_source/orcas_diff/src/main/java/de/opitzconsulting/orcas/diff/ExecuteSqlErrorHandler.java @@ -1,5 +1,7 @@ package de.opitzconsulting.orcas.diff; +import java.util.function.Supplier; + import de.opitzconsulting.orcas.diff.Parameters; import de.opitzconsulting.orcas.sql.CallableStatementProvider; @@ -17,5 +19,7 @@ interface ExecuteSqlErrorHandlerCallback { void logError(); void logInfo(String pMessage); + + String getLineReference(); } } diff --git a/orcas_core/build_source/orcas_diff/src/main/java/de/opitzconsulting/orcas/diff/OrcasMain.java b/orcas_core/build_source/orcas_diff/src/main/java/de/opitzconsulting/orcas/diff/OrcasMain.java index 5eebac41..b6334cf8 100644 --- a/orcas_core/build_source/orcas_diff/src/main/java/de/opitzconsulting/orcas/diff/OrcasMain.java +++ b/orcas_core/build_source/orcas_diff/src/main/java/de/opitzconsulting/orcas/diff/OrcasMain.java @@ -242,6 +242,11 @@ public void logError() { public void logInfo(String pMessage) { OrcasMain.this.logInfo(pMessage); } + + @Override + public String getLineReference() { + return null; + } }); } } diff --git a/orcas_core/build_source/orcas_diff/src/main/java/de/opitzconsulting/orcas/diff/OrcasScriptRunner.java b/orcas_core/build_source/orcas_diff/src/main/java/de/opitzconsulting/orcas/diff/OrcasScriptRunner.java index d52d0ad4..13d8c24b 100644 --- a/orcas_core/build_source/orcas_diff/src/main/java/de/opitzconsulting/orcas/diff/OrcasScriptRunner.java +++ b/orcas_core/build_source/orcas_diff/src/main/java/de/opitzconsulting/orcas/diff/OrcasScriptRunner.java @@ -26,6 +26,7 @@ import java.util.List; import java.util.Map; import java.util.StringTokenizer; +import java.util.function.Supplier; import de.opitzconsulting.orcas.diff.JdbcConnectionHandler.RunWithCallableStatementProvider; import de.opitzconsulting.orcas.diff.ParametersCommandline.ParameterTypeMode; @@ -264,36 +265,6 @@ void runLines(List pLines, final CallableStatementProvider pCallableStat runLines(pLines, pCallableStatementProvider, pParameters, pFile, null); } - static boolean isInComment(String pLine, boolean pWasInComment) { - boolean lIsInComment = pWasInComment; - - for (int i = 0; i < pLine.length() - 1; i++) { - if (lIsInComment) { - if (pLine.charAt(i) == '*') { - if (pLine.charAt(i + 1) == '/') { - lIsInComment = false; - i++; - } - } - } else { - if (pLine.charAt(i) == '/') { - if (pLine.charAt(i + 1) == '*') { - lIsInComment = true; - i++; - } - } - - if (pLine.charAt(i) == '-') { - if (pLine.charAt(i + 1) == '-') { - break; - } - } - } - } - - return lIsInComment; - } - void runLines( List pLines, final CallableStatementProvider pCallableStatementProvider, @@ -303,12 +274,13 @@ void runLines( inMemorySpoolFileMap.clear(); boolean lHasPlSqlModeTerminator = false; - boolean lIsInComment = false; + CommentHandler lCommentHandler = new CommentHandler(); for (String lFileLine : pLines) { String lTrimedLine = lFileLine.trim().toLowerCase(); - lIsInComment = isInComment(lTrimedLine, lIsInComment); - if (isPlsqlTerminator(lFileLine) && !lIsInComment) { + lCommentHandler.handleLine(lTrimedLine); + + if (lCommentHandler.isPlsqlTerminator(lFileLine)) { lHasPlSqlModeTerminator = true; } } @@ -365,17 +337,24 @@ public void handleCommand(String pLine, File pCurrentFile) throws Exception { lCommandHandlerList.add(createStartHandler(pCallableStatementProvider, pParameters, lSpoolHandler)); StringBuffer lCurrent = null; - lIsInComment = false; + lCommentHandler = new CommentHandler(); + int[] lStartLineIndex = new int[] { 0 }; + int[] lCurrentLineIndex = new int[] { 0 }; + + Supplier + lLineReferenceProvider = + () -> pFile + "(" + lStartLineIndex[0] + (lStartLineIndex[0] != lCurrentLineIndex[0] ? "-" + lCurrentLineIndex[0] : "") + ")"; + for (String lLine : pLines) { boolean lCurrentEnd = false; String lAppend = null; String lTrimedLine = lLine.trim().toLowerCase(); //check wether we are in a block comment - lIsInComment = isInComment(lTrimedLine, lIsInComment); + lCommentHandler.handleLine(lTrimedLine); if (lPlSqlMode) { - if (isPlsqlTerminator(lLine) && !lIsInComment) { + if (lCommentHandler.isPlsqlTerminator(lLine)) { lCurrentEnd = true; lPlSqlMode = false; } else { @@ -437,7 +416,7 @@ public void handleCommand(String pLine, File pCurrentFile) throws Exception { if (isSelect(lCurrent.toString())) { executeSelect(lCurrent.toString(), lSpoolHandler, pCallableStatementProvider); } else { - executeSql(lCurrent.toString(), pCallableStatementProvider, pParameters); + executeSql(lCurrent.toString(), pCallableStatementProvider, pParameters, lLineReferenceProvider); } if (_serveroutput) { @@ -469,20 +448,19 @@ protected void useCallableStatement(CallableStatement pCallableStatement) throws } lCurrent = null; + lStartLineIndex[0] = lCurrentLineIndex[0] + 1; } + + lCurrentLineIndex[0]++; } if (lCurrent != null && !lCurrent.toString().trim().equals("")) { - _log.error("statemmet not terminated correctly: " + lCurrent.toString()); + _log.error(lLineReferenceProvider.get() + ": statemmet not terminated correctly: " + lCurrent.toString()); } lSpoolHandler.spoolHandleFileEnd(); } - private boolean isPlsqlTerminator(String pLine) { - return pLine.trim().equals("/") && pLine.startsWith("/"); - } - protected StartHandler createStartHandler( final CallableStatementProvider pCallableStatementProvider, final Parameters pParameters, @@ -494,7 +472,7 @@ protected SpoolHandler createSpoolHandler(Parameters pParameters) { return new SpoolHandler(pParameters); } - private void executeSql(String pSql, CallableStatementProvider pCallableStatementProvider, Parameters pParameters) { + private void executeSql(String pSql, CallableStatementProvider pCallableStatementProvider, Parameters pParameters, Supplier pLineReferenceProvider) { try { new WrapperExecuteUpdate(pSql, pCallableStatementProvider).execute(); } catch (RuntimeException e) { @@ -503,17 +481,22 @@ private void executeSql(String pSql, CallableStatementProvider pCallableStatemen .handleExecutionError(e, pSql, pCallableStatementProvider, pParameters, new ExecuteSqlErrorHandler.ExecuteSqlErrorHandlerCallback() { @Override public void rethrow() { - throw new RuntimeException(e); + throw new RuntimeException(getLineReference() + e.getMessage(), e); } @Override public void logError() { - _log.warn(e, e); + _log.warn(getLineReference() + e.getMessage(), e); } @Override public void logInfo(String pMessage) { - OrcasScriptRunner.this.logInfo(pMessage); + OrcasScriptRunner.this.logInfo(getLineReference() + pMessage); + } + + @Override + public String getLineReference() { + return pLineReferenceProvider.get() + ": "; } }); } @@ -730,4 +713,49 @@ public void handleCommand(String pLine, File pCurrentFile) throws Exception { runFile(lFile, callableStatementProvider, parameters, spoolHandler); } } + + static class CommentHandler { + boolean isPlsqlTerminator(String pLine) { + return !isInComment && !isInString && pLine.trim().equals("/") && pLine.startsWith("/"); + } + + private boolean isInComment; + private boolean isInString; + + void handleLine(String pTrimedLine) { + for (int i = 0; i < pTrimedLine.length(); i++) { + if (isInComment) { + if (pTrimedLine.charAt(i) == '*') { + if (pTrimedLine.length() > i + 1 && pTrimedLine.charAt(i + 1) == '/') { + isInComment = false; + i++; + } + } + } else { + if (!isInString) { + if (pTrimedLine.charAt(i) == '/') { + if (pTrimedLine.length() > i + 1 && pTrimedLine.charAt(i + 1) == '*') { + isInComment = true; + i++; + } + } + + if (pTrimedLine.charAt(i) == '-') { + if (pTrimedLine.length() > i + 1 && pTrimedLine.charAt(i + 1) == '-') { + break; + } + } + + if (pTrimedLine.charAt(i) == '\'') { + isInString = true; + } + } else { + if (pTrimedLine.charAt(i) == '\'') { + isInString = false; + } + } + } + } + } + } } diff --git a/orcas_core/build_source/orcas_diff/src/test/java/de/opitzconsulting/orcas/diff/TestOrcasScriptRunner.java b/orcas_core/build_source/orcas_diff/src/test/java/de/opitzconsulting/orcas/diff/TestOrcasScriptRunner.java index 50cd32d9..9dd3aa0b 100644 --- a/orcas_core/build_source/orcas_diff/src/test/java/de/opitzconsulting/orcas/diff/TestOrcasScriptRunner.java +++ b/orcas_core/build_source/orcas_diff/src/test/java/de/opitzconsulting/orcas/diff/TestOrcasScriptRunner.java @@ -3,21 +3,48 @@ import org.junit.jupiter.api.Assertions; import org.junit.jupiter.api.Test; +import de.opitzconsulting.orcas.diff.OrcasScriptRunner.CommentHandler; + public class TestOrcasScriptRunner { @Test public void testIsInComment() { - Assertions.assertEquals(false, OrcasScriptRunner.isInComment("", false)); - Assertions.assertEquals(true, OrcasScriptRunner.isInComment("", true)); - Assertions.assertEquals(true, OrcasScriptRunner.isInComment(" /* odajfla", false)); - Assertions.assertEquals(false, OrcasScriptRunner.isInComment(" */ ", true)); - Assertions.assertEquals(false, OrcasScriptRunner.isInComment(" /*/ ", true)); - Assertions.assertEquals(true, OrcasScriptRunner.isInComment(" /*/ ", false)); - Assertions.assertEquals(false, OrcasScriptRunner.isInComment(" /* */ ", false)); - Assertions.assertEquals(false, OrcasScriptRunner.isInComment(" /* */ ", true)); - Assertions.assertEquals(true, OrcasScriptRunner.isInComment(" */ /* ", true)); - Assertions.assertEquals(true, OrcasScriptRunner.isInComment("*", true)); - Assertions.assertEquals(false, OrcasScriptRunner.isInComment("/", false)); - Assertions.assertEquals(false, OrcasScriptRunner.isInComment("--cxc/*", false)); - Assertions.assertEquals(false, OrcasScriptRunner.isInComment("--*/", true)); + Assertions.assertEquals(false, isInComment("", false)); + Assertions.assertEquals(true, isInComment("", true)); + Assertions.assertEquals(true, isInComment(" /* odajfla", false)); + Assertions.assertEquals(false, isInComment(" */ ", true)); + Assertions.assertEquals(false, isInComment(" /*/ ", true)); + Assertions.assertEquals(true, isInComment(" /*/ ", false)); + Assertions.assertEquals(false, isInComment(" /* */ ", false)); + Assertions.assertEquals(false, isInComment(" /* */ ", true)); + Assertions.assertEquals(true, isInComment(" */ /* ", true)); + Assertions.assertEquals(true, isInComment("*", true)); + Assertions.assertEquals(false, isInComment("/", false)); + Assertions.assertEquals(false, isInComment("--cxc/*", false)); + Assertions.assertEquals(false, isInComment("--*/", true)); + Assertions.assertEquals(false, isInComment("'/*'", false)); + Assertions.assertEquals(false, isInComment("'*/", true)); + Assertions.assertEquals(true, isInComment("'xy'/*", false)); + Assertions.assertEquals(false, isInComment("'xy''/*'", false)); + Assertions.assertEquals(false, isInComment("/*'", false, true)); + } + + private boolean isInComment(String pString, boolean pWasInComment) { + return isInComment(pString, pWasInComment, false); + } + + private boolean isInComment(String pString, boolean pWasInComment, boolean pWasInString) { + CommentHandler lCommentHandler = new CommentHandler(); + + if (pWasInComment) { + lCommentHandler.handleLine("/*"); + } else { + if (pWasInString) { + lCommentHandler.handleLine("'"); + } + } + + lCommentHandler.handleLine(pString.trim()); + + return !lCommentHandler.isPlsqlTerminator("/"); } }