From 43bc222a44ec8becf29853260764c4c7c6ad82af Mon Sep 17 00:00:00 2001
From: zhoulingfeng <330233789@qq.com>
Date: Sat, 7 Mar 2020 18:49:04 +0800
Subject: [PATCH 1/2] =?UTF-8?q?1=E3=80=81=E5=A2=9E=E5=8A=A0=E4=BA=86@raw?=
 =?UTF-8?q?=E5=85=B3=E9=94=AE=E5=AD=97=EF=BC=8C=E6=94=AF=E6=8C=81=E8=87=AA?=
 =?UTF-8?q?=E5=AE=9A=E4=B9=89where=E6=9D=A1=E4=BB=B6=E6=8B=BC=E6=8E=A5=202?=
 =?UTF-8?q?=E3=80=81=E9=83=A8=E5=88=86=E6=96=B9=E6=B3=95=E6=B3=A8=E9=87=8A?=
 =?UTF-8?q?=EF=BC=8C=E5=8F=82=E6=95=B0=E4=B8=8D=E5=AF=B9=E5=BA=94=EF=BC=8C?=
 =?UTF-8?q?=E4=BF=AE=E6=94=B9=E4=BA=86=E4=B8=8B?=
MIME-Version: 1.0
Content-Type: text/plain; charset=UTF-8
Content-Transfer-Encoding: 8bit

---
 .../apijson/demo/server/DemoSQLConfig.java    |   4 +
 .../src/main/java/apijson/JSONObject.java     |   2 +
 .../apijson/server/AbstractSQLConfig.java     | 115 ++++++++++++------
 3 files changed, 84 insertions(+), 37 deletions(-)

diff --git a/APIJSON-Java-Server/APIJSONBoot/src/main/java/apijson/demo/server/DemoSQLConfig.java b/APIJSON-Java-Server/APIJSONBoot/src/main/java/apijson/demo/server/DemoSQLConfig.java
index af5017740..c974e89c3 100755
--- a/APIJSON-Java-Server/APIJSONBoot/src/main/java/apijson/demo/server/DemoSQLConfig.java
+++ b/APIJSON-Java-Server/APIJSONBoot/src/main/java/apijson/demo/server/DemoSQLConfig.java
@@ -46,6 +46,10 @@ public class DemoSQLConfig extends AbstractSQLConfig {
 		//		TABLE_KEY_MAP.put(User.class.getSimpleName(), "apijson_user");
 		//		TABLE_KEY_MAP.put(Privacy.class.getSimpleName(), "apijson_privacy");
 
+		// 自定义where条件拼接
+		RAW_MAP.put("commentWhereItem1","`Comment`.`userId` = 38710 and `Comment`.`momentId` = 470");
+		RAW_MAP.put("commentWhereItem2","`Comment`.`toId` = 0");
+
 		//主键名映射
 		SIMPLE_CALLBACK = new SimpleCallback() {
 
diff --git a/APIJSON-Java-Server/APIJSONORM/src/main/java/apijson/JSONObject.java b/APIJSON-Java-Server/APIJSONORM/src/main/java/apijson/JSONObject.java
index e18bf3575..a0958ebeb 100755
--- a/APIJSON-Java-Server/APIJSONORM/src/main/java/apijson/JSONObject.java
+++ b/APIJSON-Java-Server/APIJSONORM/src/main/java/apijson/JSONObject.java
@@ -157,6 +157,7 @@ public JSONObject setUserIdIn(List<Object> list) {
 	public static final String KEY_HAVING = "@having"; //聚合函数条件,一般和@group一起用
 	public static final String KEY_ORDER = "@order"; //排序方式
 	public static final String KEY_JSON = "@json"; //SQL Server 把字段转为 JSON 输出
+	public static final String KEY_RAW = "@raw"; //自定义where条件拼接
 
 	public static final List<String> TABLE_KEY_LIST;
 	static {
@@ -173,6 +174,7 @@ public JSONObject setUserIdIn(List<Object> list) {
 		TABLE_KEY_LIST.add(KEY_HAVING);
 		TABLE_KEY_LIST.add(KEY_ORDER);
 		TABLE_KEY_LIST.add(KEY_JSON);
+		TABLE_KEY_LIST.add(KEY_RAW);
 	}
 
 	//@key关键字都放这个类 >>>>>>>>>>>>>>>>>>>>>>
diff --git a/APIJSON-Java-Server/APIJSONORM/src/main/java/apijson/server/AbstractSQLConfig.java b/APIJSON-Java-Server/APIJSONORM/src/main/java/apijson/server/AbstractSQLConfig.java
index 02e1a0242..1097aabcd 100755
--- a/APIJSON-Java-Server/APIJSONORM/src/main/java/apijson/server/AbstractSQLConfig.java
+++ b/APIJSON-Java-Server/APIJSONORM/src/main/java/apijson/server/AbstractSQLConfig.java
@@ -86,6 +86,8 @@ public abstract class AbstractSQLConfig implements SQLConfig {
 	 */
 	public static final Map<String, String> TABLE_KEY_MAP;
 	public static final List<String> DATABASE_LIST;
+	// 自定义where条件拼接
+	public static final Map<String, String> RAW_MAP;
 	static {
 		TABLE_KEY_MAP = new HashMap<String, String>();
 		TABLE_KEY_MAP.put(Table.class.getSimpleName(), Table.TABLE_NAME);
@@ -101,6 +103,8 @@ public abstract class AbstractSQLConfig implements SQLConfig {
 		DATABASE_LIST.add(DATABASE_POSTGRESQL);
 		DATABASE_LIST.add(DATABASE_SQLSERVER);
 		DATABASE_LIST.add(DATABASE_ORACLE);
+
+		RAW_MAP = new HashMap<>();
 	}
 
 	@Override
@@ -305,7 +309,6 @@ public String getSchema() {
 		return schema;
 	}
 	/**
-	 * @param sqlTable
 	 * @return
 	 */
 	@NotNull
@@ -1132,8 +1135,12 @@ public String getLimitString() {
 		}
 		return getLimitString(getPage(), getCount(), isOracle() || isSQLServer());
 	}
-	/**获取限制数量
-	 * @param limit
+
+	/**
+	 * 获取限制数量
+	 * @param page
+	 * @param count
+	 * @param isTSQL
 	 * @return
 	 */
 	public static String getLimitString(int page, int count, boolean isTSQL) {
@@ -1436,15 +1443,19 @@ else if ("!".equals(ce.getKey())) {
 	 * @return
 	 * @throws Exception
 	 */
-	private String getWhereItem(String key, Object value
+	public String getWhereItem(String key, Object value
 			, RequestMethod method, boolean verifyName) throws Exception {
 		Log.d(TAG, "getWhereItem  key = " + key);
 		//避免筛选到全部	value = key == null ? null : where.get(key);
-		if (key == null || value == null || key.startsWith("@") || key.endsWith("()")) {//关键字||方法, +或-直接报错
+		if(key.equals("@raw")){
+			Log.d(TAG, "getWhereItem  key startsWith @ = @raw ");
+			// 自定义where条件拼接,直接通过,放行
+		}else if (key == null || value == null || key.startsWith("@") || key.endsWith("()")) {//关键字||方法, +或-直接报错
 			Log.d(TAG, "getWhereItem  key == null || value == null"
 					+ " || key.startsWith(@) || key.endsWith(()) >> continue;");
 			return null;
 		}
+
 		if (key.endsWith("@")) {//引用
 			//	key = key.substring(0, key.lastIndexOf("@"));
 			throw new IllegalArgumentException(TAG + ".getWhereItem: 字符 " + key + " 不合法!");
@@ -1453,8 +1464,8 @@ private String getWhereItem(String key, Object value
 		int keyType;
 		if (key.endsWith("$")) {
 			keyType = 1;
-		} 
-		else if (key.endsWith("~") || key.endsWith("?")) { //TODO ?可能以后会被废弃,全用 ~ 和 *~ 替代,更接近 PostgreSQL 语法 
+		}
+		else if (key.endsWith("~") || key.endsWith("?")) { //TODO ?可能以后会被废弃,全用 ~ 和 *~ 替代,更接近 PostgreSQL 语法
 			keyType = key.charAt(key.length() - 2) == '*' ? -2 : 2;  //FIXME StringIndexOutOfBoundsException
 		}
 		else if (key.endsWith("%")) {
@@ -1481,38 +1492,61 @@ else if (key.endsWith(">")) {
 		else if (key.endsWith("<")) {
 			keyType = 10;
 		}
-		else { //else绝对不能省,避免再次踩坑! keyType = 0; 写在for循环外面都没注意!
+		else if (key.startsWith("@")) {
+			keyType = 11;
+		} else { //else绝对不能省,避免再次踩坑! keyType = 0; 写在for循环外面都没注意!
 			keyType = 0;
 		}
 		key = getRealKey(method, key, false, true, verifyName, getQuote());
 
 		switch (keyType) {
-		case 1:
-			return getSearchString(key, value);
-		case -2:
-		case 2:
-			return getRegExpString(key, value, keyType < 0);
-		case 3:
-			return getBetweenString(key, value);
-		case 4:
-			return getRangeString(key, value);
-		case 5:
-			return getExistsString(key, value);
-		case 6:
-			return getContainString(key, value);
-		case 7:
-			return getCompareString(key, value, ">=");
-		case 8:
-			return getCompareString(key, value, "<=");
-		case 9:
-			return getCompareString(key, value, ">");
-		case 10:
-			return getCompareString(key, value, "<");
-		default: //TODO MySQL JSON类型的字段对比 key='[]' 会无结果! key LIKE '[1, 2, 3]'  //TODO MySQL , 后面有空格!
-			return getEqualString(key, value);
+			case 1:
+				return getSearchString(key, value);
+			case -2:
+			case 2:
+				return getRegExpString(key, value, keyType < 0);
+			case 3:
+				return getBetweenString(key, value);
+			case 4:
+				return getRangeString(key, value);
+			case 5:
+				return getExistsString(key, value);
+			case 6:
+				return getContainString(key, value);
+			case 7:
+				return getCompareString(key, value, ">=");
+			case 8:
+				return getCompareString(key, value, "<=");
+			case 9:
+				return getCompareString(key, value, ">");
+			case 10:
+				return getCompareString(key, value, "<");
+			case 11:
+				return getRaw(key,value);
+			default: //TODO MySQL JSON类型的字段对比 key='[]' 会无结果! key LIKE '[1, 2, 3]'  //TODO MySQL , 后面有空格!
+				return getEqualString(key, value);
 		}
 	}
 
+	@JSONField(serialize = false)
+	public String getRaw(String key, Object value) throws Exception {
+		if (JSON.isBooleanOrNumberOrString(value) == false && value instanceof Subquery == false) {
+			throw new IllegalArgumentException(key + ":value 中value不合法!非PUT请求只支持 [Boolean, Number, String] 内的类型 !");
+		}
+
+		String[] rawList = ((String)value).split(",");
+		String whereItem = "";
+		for (int i = 0; i < rawList.length; i++) {
+			if(rawList.length>1&& i!=0){
+				whereItem += " and " + RAW_MAP.get(rawList[i]);
+			}else{
+				whereItem += RAW_MAP.get(rawList[i]);
+			}
+		}
+
+		return whereItem;
+	}
+
 
 	@JSONField(serialize = false)
 	public String getEqualString(String key, Object value) throws Exception {
@@ -1572,10 +1606,13 @@ public AbstractSQLConfig setPreparedValueList(List<Object> preparedValueList) {
 	}
 
 	//$ search <<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<
-	/**search key match value
-	 * @param in
+
+	/**
+	 * search key match value
+	 * @param key
+	 * @param value
 	 * @return {@link #getSearchString(String, Object[], int)}
-	 * @throws IllegalArgumentException 
+	 * @throws IllegalArgumentException
 	 */
 	@JSONField(serialize = false)
 	public String getSearchString(String key, Object value) throws IllegalArgumentException {
@@ -1593,10 +1630,14 @@ public String getSearchString(String key, Object value) throws IllegalArgumentEx
 		}
 		return getSearchString(key, arr.toArray(), logic.getType());
 	}
-	/**search key match values
-	 * @param in
+
+	/**
+	 * search key match values
+	 * @param key
+	 * @param values
+	 * @param type
 	 * @return LOGIC [  key LIKE 'values[i]' ]
-	 * @throws IllegalArgumentException 
+	 * @throws IllegalArgumentException
 	 */
 	@JSONField(serialize = false)
 	public String getSearchString(String key, Object[] values, int type) throws IllegalArgumentException {

From f0be3b15ad31ba91e62f7e491a4c2e7fa0752696 Mon Sep 17 00:00:00 2001
From: zhoulingfeng <330233789@qq.com>
Date: Fri, 13 Mar 2020 17:32:21 +0800
Subject: [PATCH 2/2] =?UTF-8?q?=E8=A7=A3=E5=86=B3PUT=E6=96=B9=E6=B3=95?=
 =?UTF-8?q?=EF=BC=8C=E6=9F=90=E4=B8=AA=E5=AD=97=E6=AE=B5=E5=8A=A0=E5=87=8F?=
 =?UTF-8?q?=E6=97=B6=EF=BC=8C=E7=B1=BB=E5=9E=8BkeyType=E6=B2=A1=E6=9C=89?=
 =?UTF-8?q?=E9=87=8D=E7=BD=AE=E7=9A=84BUG?=
MIME-Version: 1.0
Content-Type: text/plain; charset=UTF-8
Content-Transfer-Encoding: 8bit

---
 .../src/main/java/apijson/server/AbstractSQLConfig.java       | 4 +++-
 1 file changed, 3 insertions(+), 1 deletion(-)

diff --git a/APIJSON-Java-Server/APIJSONORM/src/main/java/apijson/server/AbstractSQLConfig.java b/APIJSON-Java-Server/APIJSONORM/src/main/java/apijson/server/AbstractSQLConfig.java
index 1097aabcd..f155730ff 100755
--- a/APIJSON-Java-Server/APIJSONORM/src/main/java/apijson/server/AbstractSQLConfig.java
+++ b/APIJSON-Java-Server/APIJSONORM/src/main/java/apijson/server/AbstractSQLConfig.java
@@ -2080,7 +2080,7 @@ public String getSetString(RequestMethod method, Map<String, Object> content, bo
 			String quote = getQuote();
 
 			boolean isFirst = true;
-			int keyType = 0;// 0 - =; 1 - +, 2 - -
+			int keyType;// 0 - =; 1 - +, 2 - -
 			Object value;
 
 			String idKey = getIdKey();
@@ -2094,6 +2094,8 @@ public String getSetString(RequestMethod method, Map<String, Object> content, bo
 					keyType = 1;
 				} else if (key.endsWith("-")) {
 					keyType = 2;
+				} else {
+					keyType = 0; //注意重置类型,不然不该加减的字段会跟着加减
 				}
 				value = content.get(key);
 				key = getRealKey(method, key, false, true, verifyName, quote);