Skip to content

Commit 5f5300e

Browse files
新增支持假删除
1、新增支持假删除 2、修改bug { "User_address": { "user_id!": "3123f016-a4cc-455c-aac5-264c1230dcb", "count": 11, "count+": 1, "@combine": "user_id! | count" }, "tag": "User_address", "@Explain": true } 条件 修改、删除,@combine 强制指定 "count": "" 为条件
1 parent 256dd81 commit 5f5300e

File tree

3 files changed

+108
-42
lines changed

3 files changed

+108
-42
lines changed

APIJSONORM/src/main/java/apijson/orm/AbstractSQLConfig.java

Lines changed: 99 additions & 41 deletions
Original file line numberDiff line numberDiff line change
@@ -68,8 +68,6 @@
6868
import static apijson.JSONObject.KEY_USER_ID;
6969
import static apijson.RequestMethod.DELETE;
7070
import static apijson.RequestMethod.GET;
71-
import static apijson.RequestMethod.GETS;
72-
import static apijson.RequestMethod.HEADS;
7371
import static apijson.RequestMethod.POST;
7472
import static apijson.RequestMethod.PUT;
7573
import static apijson.JSONObject.KEY_METHOD;
@@ -171,7 +169,8 @@ public abstract class AbstractSQLConfig implements SQLConfig {
171169
DATABASE_LIST.add(DATABASE_TRINO);
172170
DATABASE_LIST.add(DATABASE_INFLUXDB);
173171
DATABASE_LIST.add(DATABASE_TDENGINE);
174-
172+
DATABASE_LIST.add(DATABASE_REDIS);
173+
DATABASE_LIST.add(DATABASE_MQ);
175174

176175
RAW_MAP = new LinkedHashMap<>(); // 保证顺序,避免配置冲突等意外情况
177176

@@ -1116,6 +1115,21 @@ public static boolean isTDengine(String db) {
11161115
return DATABASE_TDENGINE.equals(db);
11171116
}
11181117

1118+
@Override
1119+
public boolean isRedis() {
1120+
return isRedis(getSQLDatabase());
1121+
}
1122+
public static boolean isRedis(String db) {
1123+
return DATABASE_REDIS.equals(db);
1124+
}
1125+
1126+
@Override
1127+
public boolean isMQ() {
1128+
return isMQ(getSQLDatabase());
1129+
}
1130+
public static boolean isMQ(String db) {
1131+
return DATABASE_MQ.equals(db);
1132+
}
11191133

11201134
@Override
11211135
public String getQuote() {
@@ -4956,10 +4970,6 @@ else if (userId instanceof Subquery) {}
49564970

49574971
//条件<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<
49584972
String[] ws = StringUtil.split(combine);
4959-
if (ws != null && (method == DELETE || method == GETS || method == HEADS)) {
4960-
throw new IllegalArgumentException(table + ":{} 里的 @combine:value 不合法!DELETE,GETS,HEADS 请求不允许传 @combine:value !");
4961-
}
4962-
49634973
String combineExpr = ws == null || ws.length != 1 ? null : ws[0];
49644974

49654975
Map<String, List<String>> combineMap = new LinkedHashMap<>();
@@ -4991,28 +5001,44 @@ else if (userId instanceof Subquery) {}
49915001
whereList.add(userIdInKey);
49925002
}
49935003

5004+
if(config.isFakeDelete()) {
5005+
// 查询Access假删除
5006+
Map<String, Object> accessFakeDeleteMap = AbstractVerifier.ACCESS_FAKE_DELETE_MAP.get(config.getTable());
5007+
if (StringUtil.isNotEmpty(accessFakeDeleteMap.get("deletedKey"), true)) {
5008+
Map<String, Object> fakeDeleteMap = new HashMap<>();
5009+
boolean isFakeDelete = true;
5010+
if(method != DELETE) {
5011+
if(from != null) {
5012+
// 兼容 join 外层select 重复生成deletedKey
5013+
if(StringUtil.equals(table, from.getConfig().getTable())) {
5014+
isFakeDelete = false;
5015+
}
5016+
5017+
if(from.getConfig().getJoinList() != null) {
5018+
for(Join join : from.getConfig().getJoinList()) {
5019+
if(StringUtil.equals(table, join.getTable())) {
5020+
isFakeDelete = false;
5021+
break;
5022+
}
5023+
}
5024+
}
5025+
}
5026+
if(isFakeDelete) {
5027+
fakeDeleteMap.put(accessFakeDeleteMap.get("deletedKey").toString()+"!", accessFakeDeleteMap.get("deletedValue"));
5028+
tableWhere.putAll(fakeDeleteMap);
5029+
andList.addAll(fakeDeleteMap.keySet());
5030+
whereList.addAll(fakeDeleteMap.keySet());
5031+
}
5032+
}
5033+
}
5034+
}
5035+
49945036
if (StringUtil.isNotEmpty(combineExpr, true)) {
49955037
List<String> banKeyList = Arrays.asList(idKey, idInKey, userIdKey, userIdInKey);
49965038
for (String key : banKeyList) {
4997-
String str = combineExpr;
4998-
while (str.isEmpty() == false) {
4999-
int index = str.indexOf(key);
5000-
if (index < 0) {
5001-
break;
5002-
}
5003-
5004-
char left = index <= 0 ? ' ' : str.charAt(index - 1);
5005-
char right = index >= str.length() - key.length() ? ' ' : str.charAt(index + key.length());
5006-
if ((left == ' ' || left == '(' || left == '&' || left == '|' || left == '!') && (right == ' ' || right == ')')) {
5007-
throw new UnsupportedOperationException(table + ":{} 里的 @combine:value 中的 value 里 " + key + " 不合法!"
5008-
+ "不允许传 [" + idKey + ", " + idInKey + ", " + userIdKey + ", " + userIdInKey + "] 其中任何一个!");
5009-
}
5010-
5011-
int newIndex = index + key.length() + 1;
5012-
if (str.length() <= newIndex) {
5013-
break;
5014-
}
5015-
str = str.substring(newIndex);
5039+
if(keyInCombineExpr(combineExpr, key)) {
5040+
throw new UnsupportedOperationException(table + ":{} 里的 @combine:value 中的 value 里 " + key + " 不合法!"
5041+
+ "不允许传 [" + idKey + ", " + idInKey + ", " + userIdKey + ", " + userIdInKey + "] 其中任何一个!");
50165042
}
50175043
}
50185044
}
@@ -5066,7 +5092,7 @@ else if (w.startsWith("!")) {
50665092
}
50675093

50685094
//条件>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>
5069-
5095+
50705096
Map<String, Object> tableContent = new LinkedHashMap<String, Object>();
50715097
Object value;
50725098
for (String key : set) {
@@ -5076,18 +5102,17 @@ else if (w.startsWith("!")) {
50765102
throw new IllegalArgumentException(table + ":{ " + key + ":value } 中 value 类型错误!除了 key<>:{} 外,不允许 " + key + " 等其它任何 key 对应 value 的类型为 JSONObject {} !");
50775103
}
50785104

5105+
//兼容 PUT @combine
50795106
//解决AccessVerifier新增userId没有作为条件,而是作为内容,导致PUT,DELETE出错
5080-
if (isWhere || (StringUtil.isName(key.replaceFirst("[+-]$", "")) == false)) {
5107+
if ((isWhere || (StringUtil.isName(key.replaceFirst("[+-]$", "")) == false)) || (isWhere == false && StringUtil.isNotEmpty(combineExpr, true) && keyInCombineExpr(combineExpr, key))) {
50815108
tableWhere.put(key, value);
50825109
if (whereList.contains(key) == false) {
50835110
andList.add(key);
50845111
}
5085-
}
5086-
else if (whereList.contains(key)) {
5112+
} else if (whereList.contains(key)) {
50875113
tableWhere.put(key, value);
5088-
}
5089-
else {
5090-
tableContent.put(key, value); //一样 instanceof JSONArray ? JSON.toJSONString(value) : value);
5114+
} else {
5115+
tableContent.put(key, value); //一样 instanceof JSONArray ? JSON.toJSONString(value) : value);
50915116
}
50925117
}
50935118

@@ -5102,6 +5127,20 @@ else if (whereList.contains(key)) {
51025127
config.setContent(tableContent);
51035128
}
51045129

5130+
if(method == DELETE) {
5131+
if(config.isFakeDelete()) {
5132+
//查询Access假删除
5133+
Map<String, Object> accessFakeDeleteMap = AbstractVerifier.ACCESS_FAKE_DELETE_MAP.get(config.getTable());
5134+
if (StringUtil.isNotEmpty(accessFakeDeleteMap.get("deletedKey"), true)) {
5135+
//​假删除需要更新的其他字段,比如:删除时间 deletedTime 之类的
5136+
Map<String, Object> fakeDeleteMap = new HashMap<>();
5137+
config.onFakeDelete(fakeDeleteMap);
5138+
fakeDeleteMap.put(accessFakeDeleteMap.get("deletedKey").toString(), accessFakeDeleteMap.get("deletedValue"));
5139+
config.setMethod(PUT);
5140+
config.setContent(fakeDeleteMap);
5141+
}
5142+
}
5143+
}
51055144

51065145
List<String> cs = new ArrayList<>();
51075146

@@ -5494,14 +5533,12 @@ else if (key.endsWith("-")) {//缩减,PUT查询时处理
54945533

54955534
//TODO if (key.endsWith("-")) { // 表示 key 和 value 顺序反过来: value LIKE key
54965535

5497-
String last = null;//不用Logic优化代码,否则 key 可能变为 key| 导致 key=value 变成 key|=value 而出错
5498-
if (RequestMethod.isQueryMethod(method)) {//逻辑运算符仅供GET,HEAD方法使用
5499-
last = key.isEmpty() ? "" : key.substring(key.length() - 1);
5500-
if ("&".equals(last) || "|".equals(last) || "!".equals(last)) {
5501-
key = key.substring(0, key.length() - 1);
5502-
} else {
5503-
last = null;//避免key + StringUtil.getString(last)错误延长
5504-
}
5536+
//不用Logic优化代码,否则 key 可能变为 key| 导致 key=value 变成 key|=value 而出错
5537+
String last = key.isEmpty() ? "" : key.substring(key.length() - 1);
5538+
if ("&".equals(last) || "|".equals(last) || "!".equals(last)) {
5539+
key = key.substring(0, key.length() - 1);
5540+
} else {
5541+
last = null;//避免key + StringUtil.getString(last)错误延长
55055542
}
55065543

55075544
//"User:toUser":User转换"toUser":User, User为查询同名Table得到的JSONObject。交给客户端处理更好
@@ -5606,6 +5643,27 @@ public void onMissingKey4Combine(String name, JSONObject request, String combine
56065643

56075644
}
56085645

5646+
private static boolean keyInCombineExpr(String combineExpr, String key) {
5647+
while (combineExpr.isEmpty() == false) {
5648+
int index = combineExpr.indexOf(key);
5649+
if (index < 0) {
5650+
return false;
5651+
}
5652+
5653+
char left = index <= 0 ? ' ' : combineExpr.charAt(index - 1);
5654+
char right = index >= combineExpr.length() - key.length() ? ' ' : combineExpr.charAt(index + key.length());
5655+
if ((left == ' ' || left == '(' || left == '&' || left == '|' || left == '!') && (right == ' ' || right == ')')) {
5656+
return true;
5657+
}
5658+
int newIndex = index + key.length() + 1;
5659+
if (combineExpr.length() <= newIndex) {
5660+
break;
5661+
}
5662+
combineExpr = combineExpr.substring(newIndex);
5663+
}
5664+
return false;
5665+
}
5666+
56095667
private void setWithAsExpreList() {
56105668
// mysql8版本以上,子查询支持with as表达式
56115669
if(this.isMySQL() && this.getDBVersionNums()[0] >= 8) {

APIJSONORM/src/main/java/apijson/orm/AbstractVerifier.java

Lines changed: 2 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -127,6 +127,8 @@ public abstract class AbstractVerifier<T extends Object> implements Verifier<T>,
127127
public static Map<String, Map<RequestMethod, String[]>> SYSTEM_ACCESS_MAP;
128128
@NotNull
129129
public static Map<String, Map<RequestMethod, String[]>> ACCESS_MAP;
130+
@NotNull
131+
public static Map<String, Map<String, Object>> ACCESS_FAKE_DELETE_MAP;
130132

131133
// <method tag, <version, Request>>
132134
// <PUT Comment, <1, { "method":"PUT", "tag":"Comment", "structure":{ "MUST":"id"... }... }>>

APIJSONORM/src/main/java/apijson/orm/SQLConfig.java

Lines changed: 7 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -33,7 +33,8 @@ public interface SQLConfig {
3333
String DATABASE_TRINO = "TRINO"; // PrestoSQL https://trino.io
3434
String DATABASE_INFLUXDB = "INFLUXDB"; // https://www.influxdata.com/products/influxdb-overview
3535
String DATABASE_TDENGINE = "TDENGINE"; // https://tdengine.com
36-
36+
String DATABASE_REDIS = "REDIS";
37+
String DATABASE_MQ = "MQ";
3738

3839
String SCHEMA_INFORMATION = "information_schema"; //MySQL, PostgreSQL, SQL Server 都有的系统模式
3940
String SCHEMA_SYS = "sys"; //SQL Server 系统模式
@@ -60,6 +61,8 @@ public interface SQLConfig {
6061
boolean isTrino();
6162
boolean isInfluxDB();
6263
boolean isTDengine();
64+
boolean isRedis();
65+
boolean isMQ();
6366

6467

6568
//暂时只兼容以上几种
@@ -317,4 +320,7 @@ default int[] getDBVersionNums() {
317320
List<Object> getWithAsExprePreparedValueList();
318321
void setWithAsExprePreparedValueList(List<Object> withAsExprePreparedValueList);
319322

323+
boolean isFakeDelete();
324+
325+
void onFakeDelete(Map<String, Object> map);
320326
}

0 commit comments

Comments
 (0)