|
@@ -21,7 +21,6 @@ import java.util.ArrayList;
|
|
|
import java.util.HashMap;
|
|
import java.util.HashMap;
|
|
|
import java.util.List;
|
|
import java.util.List;
|
|
|
import java.util.Map;
|
|
import java.util.Map;
|
|
|
-import java.util.regex.Matcher;
|
|
|
|
|
import java.util.regex.Pattern;
|
|
import java.util.regex.Pattern;
|
|
|
|
|
|
|
|
@Component
|
|
@Component
|
|
@@ -95,18 +94,37 @@ public class DatabaseInitializer implements CommandLineRunner {
|
|
|
// Remove SQL single-line comments
|
|
// Remove SQL single-line comments
|
|
|
content = content.replaceAll("(?m)^\\s*--.*$", "");
|
|
content = content.replaceAll("(?m)^\\s*--.*$", "");
|
|
|
|
|
|
|
|
- // Extract all CREATE TABLE IF NOT EXISTS statements
|
|
|
|
|
- Pattern pattern = Pattern.compile(
|
|
|
|
|
- "CREATE\\s+TABLE\\s+IF\\s+NOT\\s+EXISTS\\s+.*?;",
|
|
|
|
|
- Pattern.CASE_INSENSITIVE | Pattern.DOTALL
|
|
|
|
|
- );
|
|
|
|
|
- Matcher matcher = pattern.matcher(content);
|
|
|
|
|
-
|
|
|
|
|
|
|
+ // 提取所有 CREATE TABLE IF NOT EXISTS 语句。
|
|
|
|
|
+ // 不能用非贪婪 ".*?;" 匹配:COMMENT 字符串字面量中可能含分号(如
|
|
|
|
|
+ // task_reminder_config.offset_minutes 的注释 "截止前N分钟; after_timeout..."),
|
|
|
|
|
+ // 会被提前截断导致语句不完整而建表失败。此处按字符扫描,跳过引号内部的分号。
|
|
|
List<String> createTableSQLs = new ArrayList<>();
|
|
List<String> createTableSQLs = new ArrayList<>();
|
|
|
- while (matcher.find()) {
|
|
|
|
|
- String sql = matcher.group().trim();
|
|
|
|
|
- if (!sql.isEmpty()) {
|
|
|
|
|
- createTableSQLs.add(sql);
|
|
|
|
|
|
|
+ Pattern createTableHead = Pattern.compile(
|
|
|
|
|
+ "^\\s*CREATE\\s+TABLE\\s+IF\\s+NOT\\s+EXISTS\\b", Pattern.CASE_INSENSITIVE);
|
|
|
|
|
+ StringBuilder stmt = new StringBuilder();
|
|
|
|
|
+ boolean inSingleQuote = false;
|
|
|
|
|
+ boolean inBacktick = false;
|
|
|
|
|
+ for (int i = 0; i < content.length(); i++) {
|
|
|
|
|
+ char c = content.charAt(i);
|
|
|
|
|
+ if (c == '\'' && !inBacktick) {
|
|
|
|
|
+ if (inSingleQuote && i + 1 < content.length() && content.charAt(i + 1) == '\'') {
|
|
|
|
|
+ stmt.append("''");
|
|
|
|
|
+ i++;
|
|
|
|
|
+ continue;
|
|
|
|
|
+ }
|
|
|
|
|
+ inSingleQuote = !inSingleQuote;
|
|
|
|
|
+ stmt.append(c);
|
|
|
|
|
+ } else if (c == '`' && !inSingleQuote) {
|
|
|
|
|
+ inBacktick = !inBacktick;
|
|
|
|
|
+ stmt.append(c);
|
|
|
|
|
+ } else if (c == ';' && !inSingleQuote && !inBacktick) {
|
|
|
|
|
+ String sql = stmt.toString().trim();
|
|
|
|
|
+ if (!sql.isEmpty() && createTableHead.matcher(sql).find()) {
|
|
|
|
|
+ createTableSQLs.add(sql + ";");
|
|
|
|
|
+ }
|
|
|
|
|
+ stmt.setLength(0);
|
|
|
|
|
+ } else {
|
|
|
|
|
+ stmt.append(c);
|
|
|
}
|
|
}
|
|
|
}
|
|
}
|
|
|
|
|
|