Skip to content

Commit e0f4de3

Browse files
committed
update
1 parent a9c76c9 commit e0f4de3

File tree

14 files changed

+506
-2
lines changed

14 files changed

+506
-2
lines changed

.gitignore

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -32,4 +32,4 @@ build/
3232
### VS Code ###
3333
.vscode/
3434
*.db
35-
dbstream
35+
.dbstream/
Lines changed: 71 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,71 @@
1+
package com.codingapi.dbstream.sqlparser;
2+
3+
import com.codingapi.dbstream.utils.SQLUtils;
4+
5+
import java.util.regex.Matcher;
6+
import java.util.regex.Pattern;
7+
8+
public class DeleteSQLParser {
9+
10+
private final String sql;
11+
12+
13+
// 匹配 INSERT INTO table_name (...)
14+
private static final Pattern TABLE_NAME_PATTERN = Pattern.compile(
15+
"(?i)DELETE(?:\\s+[\\w,\\s]+)?\\s+FROM\\s+([\\w\\.\\[\\]\"`]+)",
16+
Pattern.CASE_INSENSITIVE
17+
);
18+
19+
public DeleteSQLParser(String sql) {
20+
this.sql = SQLUtils.normalize(sql);
21+
}
22+
23+
/**
24+
* 提取表名(兼容 schema.table, 支持方括号/引号)
25+
*/
26+
public String getTableName() {
27+
Matcher matcher = TABLE_NAME_PATTERN.matcher(sql);
28+
if (matcher.find()) {
29+
return SQLUtils.stripQuotes(matcher.group(1));
30+
}
31+
return null;
32+
}
33+
34+
/**
35+
* 提取别名(支持 AS、方括号/引号;避免把 SQL 关键字当成别名)
36+
*/
37+
public String getTableAlias() {
38+
if (sql.isEmpty()) return null;
39+
40+
// 1. 获取表名
41+
String tableName = getTableName();
42+
if (tableName == null || tableName.isEmpty()) return null;
43+
44+
// 2. 构造匹配模式:FROM tableName [AS] alias
45+
String regex = String.format(
46+
"(?i)FROM\\s+[`\"\\[]?%s[`\"\\]]?(?:\\s+AS)?\\s+([A-Za-z_][A-Za-z0-9_]*)",
47+
Pattern.quote(tableName)
48+
);
49+
Pattern pattern = Pattern.compile(regex, Pattern.CASE_INSENSITIVE);
50+
Matcher matcher = pattern.matcher(sql);
51+
52+
if (matcher.find()) {
53+
String alias = matcher.group(1);
54+
// 避免误匹配 SQL 关键字
55+
if (!SQLUtils.isSQLKeyword(alias)) {
56+
return alias;
57+
}
58+
}
59+
return null;
60+
}
61+
62+
63+
/**
64+
* 提取 WHERE 部分(保留后面的所有内容)
65+
*/
66+
public String getWhereSQL() {
67+
return SQLUtils.getWhereSQL(sql);
68+
}
69+
70+
71+
}
Lines changed: 84 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,84 @@
1+
package com.codingapi.dbstream.sqlparser;
2+
3+
import com.codingapi.dbstream.utils.SQLUtils;
4+
5+
import java.util.ArrayList;
6+
import java.util.List;
7+
import java.util.regex.Matcher;
8+
import java.util.regex.Pattern;
9+
10+
public class InsertSQLParser {
11+
12+
// 匹配 INSERT INTO table_name (...)
13+
private static final Pattern TABLE_NAME_PATTERN = Pattern.compile(
14+
"(?i)INSERT\\s+INTO\\s+([`\"\\[]?[\\w.]+[`\"\\]]?)",
15+
Pattern.CASE_INSENSITIVE
16+
);
17+
18+
// 匹配列部分:(col1, col2, col3)
19+
private static final Pattern COLUMNS_PATTERN = Pattern.compile(
20+
"\\(([^)]+)\\)\\s*(?i)(VALUES|SELECT)"
21+
);
22+
23+
private final String sql;
24+
25+
public InsertSQLParser(String sql) {
26+
this.sql = SQLUtils.normalize(sql);
27+
}
28+
29+
/**
30+
* 提取表名
31+
* 示例: INSERT INTO `user` (id,name) VALUES (?,?) → user
32+
*/
33+
public String getTableName() {
34+
Matcher matcher = TABLE_NAME_PATTERN.matcher(sql);
35+
if (matcher.find()) {
36+
return SQLUtils.stripQuotes(matcher.group(1));
37+
}
38+
return null;
39+
}
40+
41+
/**
42+
* 提取插入的字段名称
43+
* 示例: INSERT INTO user (id,name,age) VALUES (?,?,?)
44+
* 输出: ["id", "name", "age"]
45+
*/
46+
public List<String> getColumnValues() {
47+
Matcher matcher = COLUMNS_PATTERN.matcher(sql);
48+
if (matcher.find()) {
49+
String cols = matcher.group(1);
50+
String[] parts = cols.split(",");
51+
List<String> columns = new ArrayList<>();
52+
for (String col : parts) {
53+
col = SQLUtils.stripQuotes(col.trim());
54+
if (!col.isEmpty()) {
55+
columns.add(col);
56+
}
57+
}
58+
return columns;
59+
}
60+
return new ArrayList<>();
61+
}
62+
63+
/**
64+
* 提取 SELECT 或 VALUES 后面的 SQL 内容(包含完整结构)
65+
* 示例:
66+
* INSERT INTO user (id,name) SELECT id,name FROM other
67+
* → SELECT id,name FROM other
68+
*
69+
* INSERT INTO user (id,name) VALUES (?,?)
70+
* → VALUES (?,?)
71+
*/
72+
public String getSelectSQL() {
73+
// 匹配 VALUES 或 SELECT 后面的内容
74+
Pattern p = Pattern.compile("(?i)\\b(SELECT)\\b\\s+(.*)$", Pattern.DOTALL);
75+
Matcher m = p.matcher(sql);
76+
if (m.find()) {
77+
String keyword = m.group(1).toUpperCase();
78+
String rest = m.group(2).trim();
79+
return keyword + " " + rest;
80+
}
81+
return null;
82+
}
83+
84+
}
Lines changed: 109 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,109 @@
1+
package com.codingapi.dbstream.sqlparser;
2+
3+
import com.codingapi.dbstream.utils.SQLUtils;
4+
5+
import java.util.ArrayList;
6+
import java.util.List;
7+
import java.util.regex.Matcher;
8+
import java.util.regex.Pattern;
9+
10+
public class UpdateSQLParser {
11+
12+
private final String sql;
13+
14+
private static final Pattern TABLE_NAME_PATTERN = Pattern.compile(
15+
"(?i)UPDATE\\s+([\\w\\.\\[\\]\"`]+)"
16+
);
17+
18+
public UpdateSQLParser(String sql) {
19+
this.sql = SQLUtils.normalize(sql);
20+
}
21+
22+
/**
23+
* 提取表名(兼容 schema.table, 支持方括号/引号)
24+
*/
25+
public String getTableName() {
26+
Matcher matcher = TABLE_NAME_PATTERN.matcher(sql);
27+
if (matcher.find()) {
28+
return SQLUtils.stripQuotes(matcher.group(1));
29+
}
30+
return null;
31+
}
32+
33+
34+
/**
35+
* 提取别名(支持 AS、方括号/引号;避免把 SQL 关键字当成别名)
36+
*/
37+
public String getTableAlias() {
38+
if (sql == null || sql.isEmpty()) {
39+
return null;
40+
}
41+
42+
String tableName = getTableName();
43+
if (tableName == null || tableName.isEmpty()) {
44+
return null;
45+
}
46+
47+
// 匹配 UPDATE tableName [AS] alias
48+
String regex = "(?i)UPDATE\\s+[`\"\\[]?" + Pattern.quote(tableName)
49+
+ "[`\"\\]]?(?:\\s+AS)?\\s+([A-Za-z_][A-Za-z0-9_]*)";
50+
Pattern pattern = Pattern.compile(regex);
51+
Matcher matcher = pattern.matcher(sql);
52+
53+
if (matcher.find()) {
54+
String alias = matcher.group(1);
55+
if (!SQLUtils.isSQLKeyword(alias)) {
56+
return alias;
57+
}
58+
}
59+
return null;
60+
}
61+
62+
63+
/**
64+
* 提取 SET 后面的字段名
65+
* 示例: SET name=?, age=?, updated_at=NOW()
66+
*/
67+
public List<String> getColumnValues() {
68+
List<String> columns = new ArrayList<>();
69+
70+
// 匹配 SET 后的内容
71+
Pattern setPattern = Pattern.compile("(?i)\\bSET\\b\\s+(.*?)(?=\\bWHERE\\b|$)", Pattern.DOTALL);
72+
Matcher matcher = setPattern.matcher(sql);
73+
if (matcher.find()) {
74+
String setPart = matcher.group(1).trim();
75+
76+
// 分割字段赋值(按逗号分割)
77+
String[] parts = setPart.split(",");
78+
for (String part : parts) {
79+
String[] kv = part.split("=", 2);
80+
if (kv.length > 0) {
81+
String col = kv[0].trim();
82+
83+
// 如果字段是带表别名的,如 "u.name"
84+
int dotIndex = col.lastIndexOf('.');
85+
if (dotIndex > 0) {
86+
col = col.substring(dotIndex + 1);
87+
}
88+
89+
col = SQLUtils.stripQuotes(col);
90+
if (!col.isEmpty()) {
91+
columns.add(col);
92+
}
93+
}
94+
}
95+
}
96+
97+
return columns;
98+
}
99+
100+
101+
/**
102+
* 提取 WHERE 部分(保留后面的所有内容)
103+
*/
104+
public String getWhereSQL() {
105+
return SQLUtils.getWhereSQL(sql);
106+
}
107+
108+
109+
}

src/main/java/com/codingapi/dbstream/utils/DBTableSerializableHelper.java

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -13,7 +13,7 @@ public class DBTableSerializableHelper {
1313
private final File path;
1414

1515
public DBTableSerializableHelper(String jdbcKey) {
16-
this.path = new File("./dbstream/" + jdbcKey + "/");
16+
this.path = new File("./.dbstream/" + jdbcKey + "/");
1717
if (!this.path.exists()) {
1818
boolean parentResult = path.getParentFile().mkdir();
1919
boolean currentResult = path.mkdir();
Lines changed: 18 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,18 @@
1+
package com.codingapi.dbstream.utils;
2+
3+
public class ResultSetUtils {
4+
5+
public static boolean isNotUpdatedRows(Object result) {
6+
if (result instanceof Integer) {
7+
int value = (Integer) result;
8+
return value <= 0;
9+
}
10+
11+
if (result instanceof Long) {
12+
long value = (Long) result;
13+
return value <= 0;
14+
}
15+
return false;
16+
}
17+
18+
}
Lines changed: 25 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,25 @@
1+
package com.codingapi.dbstream.utils;
2+
3+
import java.nio.charset.StandardCharsets;
4+
import java.security.MessageDigest;
5+
6+
public class SHA256Utils {
7+
8+
public static String sha256(String text) {
9+
try {
10+
MessageDigest digest = MessageDigest.getInstance("SHA-256");
11+
byte[] hash = digest.digest(text.getBytes(StandardCharsets.UTF_8));
12+
StringBuilder hexString = new StringBuilder();
13+
for (byte b : hash) {
14+
// 每个字节转换为两位十六进制
15+
String hex = Integer.toHexString(0xff & b);
16+
if (hex.length() == 1) hexString.append('0');
17+
hexString.append(hex);
18+
}
19+
return hexString.toString();
20+
} catch (Exception e) {
21+
throw new RuntimeException(e);
22+
}
23+
}
24+
25+
}

0 commit comments

Comments
 (0)