in core/src/main/java/com/jetbrains/youtrackdb/internal/core/command/script/CommandExecutorScript.java [274:477]
protected Object executeSQLScript(final String iText, final DatabaseSessionEmbedded db)
throws IOException {
Object lastResult = null;
var maxRetry = 1;
context.setVariable("transactionRetries", 0);
context.setVariable("parentQuery", this);
for (var retry = 1; retry <= maxRetry; retry++) {
try {
try {
var txBegunAtLine = -1;
var txBegunAtPart = -1;
lastResult = null;
var nestedLevel = 0;
var skippingScriptsAtNestedLevel = -1;
final var reader = new BufferedReader(new StringReader(iText));
var line = 0;
var linePart = 0;
String lastLine;
var txBegun = false;
for (; line < txBegunAtLine; ++line)
// SKIP PREVIOUS COMMAND AND JUMP TO THE BEGIN IF ANY
{
reader.readLine();
}
for (; (lastLine = reader.readLine()) != null; ++line) {
lastLine = lastLine.trim();
// this block is here (and not below, with the other conditions)
// just because of the smartSprit() that does not parse correctly a single bracket
// final List<String> lineParts = StringSerializerHelper.smartSplit(lastLine, ';',
// true);
final var lineParts = splitBySemicolon(lastLine);
if (line == txBegunAtLine)
// SKIP PREVIOUS COMMAND PART AND JUMP TO THE BEGIN IF ANY
{
linePart = txBegunAtPart;
} else {
linePart = 0;
}
var breakReturn = false;
for (; linePart < lineParts.size(); ++linePart) {
final var lastCommand = lineParts.get(linePart);
if (isIfCondition(lastCommand)) {
nestedLevel++;
if (skippingScriptsAtNestedLevel >= 0) {
continue; // I'm in an (outer) IF that did not match the condition
}
var ifResult = evaluateIfCondition(db.getDatabaseName(), lastCommand);
if (!ifResult) {
// if does not match the condition, skip all the inner statements
skippingScriptsAtNestedLevel = nestedLevel;
}
continue;
} else if (lastCommand.equals("}")) {
nestedLevel--;
if (skippingScriptsAtNestedLevel > nestedLevel) {
skippingScriptsAtNestedLevel = -1;
}
continue;
} else if (skippingScriptsAtNestedLevel >= 0) {
continue; // I'm in an IF that did not match the condition
} else if (StringSerializerHelper.startsWithIgnoreCase(lastCommand, "let ")) {
lastResult = executeLet(lastCommand, db);
} else if (StringSerializerHelper.startsWithIgnoreCase(lastCommand, "begin")) {
if (txBegun) {
throw new CommandSQLParsingException(db.getDatabaseName(),
"Transaction already begun");
}
if (db.getTransactionInternal().isActive())
// COMMIT ANY ACTIVE TX
{
db.commit();
}
txBegun = true;
txBegunAtLine = line;
txBegunAtPart = linePart;
db.begin();
} else if ("rollback".equalsIgnoreCase(lastCommand)) {
if (!txBegun) {
throw new CommandSQLParsingException(db.getDatabaseName(),
"Transaction not begun");
}
db.rollback();
txBegun = false;
txBegunAtLine = -1;
txBegunAtPart = -1;
} else if (StringSerializerHelper.startsWithIgnoreCase(lastCommand, "commit")) {
if (txBegunAtLine < 0) {
throw new CommandSQLParsingException(db.getDatabaseName(),
"Transaction not begun");
}
if (retry == 1 && lastCommand.length() > "commit ".length()) {
// FIRST CYCLE: PARSE RETRY TIMES OVERWRITING DEFAULT = 1
var next = lastCommand.substring("commit ".length()).trim();
if (StringSerializerHelper.startsWithIgnoreCase(next, "retry ")) {
next = next.substring("retry ".length()).trim();
maxRetry = Integer.parseInt(next);
}
}
db.commit();
txBegun = false;
txBegunAtLine = -1;
txBegunAtPart = -1;
} else if (StringSerializerHelper.startsWithIgnoreCase(lastCommand, "sleep ")) {
executeSleep(lastCommand);
} else if (StringSerializerHelper.startsWithIgnoreCase(
lastCommand, "console.log ")) {
executeConsoleLog(lastCommand, db);
} else if (StringSerializerHelper.startsWithIgnoreCase(
lastCommand, "console.output ")) {
executeConsoleOutput(lastCommand, db);
} else if (StringSerializerHelper.startsWithIgnoreCase(
lastCommand, "console.error ")) {
executeConsoleError(lastCommand, db);
} else if (StringSerializerHelper.startsWithIgnoreCase(lastCommand, "return ")) {
lastResult = getValue(lastCommand.substring("return ".length()), db);
// END OF SCRIPT
breakReturn = true;
break;
} else if (lastCommand != null && lastCommand.length() > 0) {
lastResult = executeCommand(lastCommand, db);
}
}
if (breakReturn) {
break;
}
}
} catch (RuntimeException ex) {
if (db.getTransactionInternal().isActive()) {
db.rollback();
}
throw ex;
}
// COMPLETED
break;
} catch (TransactionException e) {
// THIS CASE IS ON UPSERT
context.setVariable("retries", retry);
if (retry >= maxRetry) {
throw e;
}
waitForNextRetry();
} catch (RecordDuplicatedException e) {
// THIS CASE IS ON UPSERT
context.setVariable("retries", retry);
if (retry >= maxRetry) {
throw e;
}
waitForNextRetry();
} catch (RecordNotFoundException e) {
// THIS CASE IS ON UPSERT
context.setVariable("retries", retry);
if (retry >= maxRetry) {
throw e;
}
} catch (NeedRetryException e) {
context.setVariable("retries", retry);
if (retry >= maxRetry) {
throw e;
}
waitForNextRetry();
}
}
return lastResult;
}