From 5eac725a3eebf62e6c8f7c89d117d16170e3d8b7 Mon Sep 17 00:00:00 2001 From: kxlv2000 <49295281+kxlv2000@users.noreply.github.com> Date: Wed, 19 May 2021 21:54:05 +0800 Subject: [PATCH 01/17] =?UTF-8?q?=E4=BC=98=E5=8C=96=20system.err.printlin?= =?UTF-8?q?=20=E8=BE=93=E5=87=BA?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit issure #232 --- .../main/java/apijson/orm/AbstractParser.java | 35 +++++++++++++------ 1 file changed, 25 insertions(+), 10 deletions(-) diff --git a/APIJSONORM/src/main/java/apijson/orm/AbstractParser.java b/APIJSONORM/src/main/java/apijson/orm/AbstractParser.java index e109b5a04..1525941b9 100755 --- a/APIJSONORM/src/main/java/apijson/orm/AbstractParser.java +++ b/APIJSONORM/src/main/java/apijson/orm/AbstractParser.java @@ -48,11 +48,24 @@ public abstract class AbstractParser implements Parser, ParserCreator, VerifierCreator, SQLCreator { protected static final String TAG = "AbstractParser"; + /** + * 可以通过切换该变量来控制是否打印关键的接口请求内容。保守起见,该值默认为false。 + * 与 {@link Log#DEBUG} 任何一个为 true 都会打印关键的接口请求内容。 + */ + public static boolean IS_PRINT_REQUEST_STRING_LOG = true; + /** * 打印大数据量日志的标识。线上环境比较敏感,可以通过切换该变量来控制异常栈抛出、错误日志打印。保守起见,该值默认为false。 * 与 {@link Log#DEBUG} 任何一个为 true 都会打印关键的接口请求及响应信息。 */ - public static boolean IS_PRINT_BIG_LOG = false; + public static boolean IS_PRINT_BIG_LOG = true; + + /** + * 可以通过切换该变量来控制是否打印关键的接口请求结束时间。保守起见,该值默认为false。 + * 与 {@link Log#DEBUG} 任何一个为 true 都会打印关键的接口请求结束时间。 + */ + public static boolean IS_PRINT_REQUEST_ENDTIME_LOG = true; + /** * method = null @@ -400,16 +413,18 @@ public JSONObject parseResponse(JSONObject request) { onClose(); - System.err.println("\n\n\n\n<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<\n " - + TAG + ".DEBUG: " + requestMethod + "/parseResponse request = \n" + requestString + "\n\n"); - - if (Log.DEBUG || IS_PRINT_BIG_LOG || error != null) { // 日志仅存服务器,所以不太敏感,而且这些日志虽然量大但非常重要,对排查 bug 很关键 - System.err.println(TAG + ".DEBUG: " + requestMethod + "/parseResponse return response = \n" + JSON.toJSONString(requestObject) + "\n\n"); + //CS304 Issue link: https://github.com/Tencent/APIJSON/issues/232 + if (IS_PRINT_REQUEST_STRING_LOG||Log.DEBUG||error != null) { + Log.sl("\n\n\n",'<',""); + Log.fd(TAG , requestMethod + "/parseResponse request = \n" + requestString + "\n\n"); + } + if (IS_PRINT_BIG_LOG||Log.DEBUG||error != null) { // 日志仅存服务器,所以不太敏感,而且这些日志虽然量大但非常重要,对排查 bug 很关键 + Log.fd(TAG,requestMethod + "/parseResponse return response = \n" + JSON.toJSONString(requestObject) + "\n\n"); + } + if (IS_PRINT_REQUEST_ENDTIME_LOG||Log.DEBUG||error != null) { + Log.fd(TAG , requestMethod + "/parseResponse endTime = " + endTime + "; duration = " + duration); + Log.sl("",'>',"\n\n\n"); } - - System.err.println(TAG + ".DEBUG: " + requestMethod + "/parseResponse endTime = " + endTime + "; duration = " + duration - + "\n>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>> \n\n\n"); - return res; } From c932f0b1bac50699bae3e83c99326ea11686db76 Mon Sep 17 00:00:00 2001 From: kxlv2000 <49295281+kxlv2000@users.noreply.github.com> Date: Wed, 19 May 2021 22:09:27 +0800 Subject: [PATCH 02/17] =?UTF-8?q?=E4=BC=98=E5=8C=96=20system.err.printlin?= =?UTF-8?q?=20=E8=BE=93=E5=87=BA?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit issue Tencent#232 --- APIJSONORM/src/main/java/apijson/Log.java | 19 +++++++++++++++++++ .../main/java/apijson/orm/AbstractParser.java | 6 +++--- 2 files changed, 22 insertions(+), 3 deletions(-) diff --git a/APIJSONORM/src/main/java/apijson/Log.java b/APIJSONORM/src/main/java/apijson/Log.java index d37691f8e..eecc7e1c2 100755 --- a/APIJSONORM/src/main/java/apijson/Log.java +++ b/APIJSONORM/src/main/java/apijson/Log.java @@ -22,6 +22,25 @@ public static void d(String TAG, String msg) { } } + /** + * Forced debug + * @param TAG tag + * @param msg debug messages + */ + public static void fd(String TAG, String msg) { + System.err.println(TAG + ".DEBUG: " + msg); + } + + /** + * Generate separation line + * @param pre prefix + * @param symbol used for generating separation line + * @param post postfix + */ + public static void sl(String pre,char symbol ,String post) { + System.err.println(pre+new String(new char[48]).replace('\u0000', symbol)+post); + } + /** * @param TAG * @param msg diff --git a/APIJSONORM/src/main/java/apijson/orm/AbstractParser.java b/APIJSONORM/src/main/java/apijson/orm/AbstractParser.java index 1525941b9..c46e82e4e 100755 --- a/APIJSONORM/src/main/java/apijson/orm/AbstractParser.java +++ b/APIJSONORM/src/main/java/apijson/orm/AbstractParser.java @@ -52,19 +52,19 @@ public abstract class AbstractParser implements Parser, ParserCreator, * 可以通过切换该变量来控制是否打印关键的接口请求内容。保守起见,该值默认为false。 * 与 {@link Log#DEBUG} 任何一个为 true 都会打印关键的接口请求内容。 */ - public static boolean IS_PRINT_REQUEST_STRING_LOG = true; + public static boolean IS_PRINT_REQUEST_STRING_LOG = false; /** * 打印大数据量日志的标识。线上环境比较敏感,可以通过切换该变量来控制异常栈抛出、错误日志打印。保守起见,该值默认为false。 * 与 {@link Log#DEBUG} 任何一个为 true 都会打印关键的接口请求及响应信息。 */ - public static boolean IS_PRINT_BIG_LOG = true; + public static boolean IS_PRINT_BIG_LOG = false; /** * 可以通过切换该变量来控制是否打印关键的接口请求结束时间。保守起见,该值默认为false。 * 与 {@link Log#DEBUG} 任何一个为 true 都会打印关键的接口请求结束时间。 */ - public static boolean IS_PRINT_REQUEST_ENDTIME_LOG = true; + public static boolean IS_PRINT_REQUEST_ENDTIME_LOG = false; /** From 96809de85db9dae3c9c8799e6dc11e540dff0789 Mon Sep 17 00:00:00 2001 From: Rkyzzy <982993741@qq.com> Date: Thu, 20 May 2021 19:40:17 +0800 Subject: [PATCH 03/17] =?UTF-8?q?fix:=20=E6=9B=B4=E6=96=B0=E4=B8=BA?= =?UTF-8?q?=E6=9C=80=E6=96=B0=E7=9A=84=E6=89=8B=E6=9C=BA=E5=8F=B7=E6=AD=A3?= =?UTF-8?q?=E5=88=99=E8=A1=A8=E8=BE=BE=E5=BC=8F=E5=8C=B9=E9=85=8D=20issue#?= =?UTF-8?q?240?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- APIJSONORM/src/main/java/apijson/StringUtil.java | 3 ++- 1 file changed, 2 insertions(+), 1 deletion(-) diff --git a/APIJSONORM/src/main/java/apijson/StringUtil.java b/APIJSONORM/src/main/java/apijson/StringUtil.java index fc9552de4..671f04ae0 100755 --- a/APIJSONORM/src/main/java/apijson/StringUtil.java +++ b/APIJSONORM/src/main/java/apijson/StringUtil.java @@ -311,7 +311,8 @@ public static boolean isNotEmpty(String s, boolean trim) { PATTERN_ALPHA_BIG = Pattern.compile("^[A-Z]+$"); PATTERN_ALPHA_SMALL = Pattern.compile("^[a-z]+$"); PATTERN_NAME = Pattern.compile("^[0-9a-zA-Z_]+$");//已用55个中英字符测试通过 - PATTERN_PHONE = Pattern.compile("^((13[0-9])|(15[^4,\\D])|(18[0-2,5-9])|(17[0-9]))\\d{8}$"); + //PATTERN_PHONE = Pattern.compile("^((13[0-9])|(15[^4,\\D])|(18[0-2,5-9])|(17[0-9]))\\d{8}$"); + PATTERN_PHONE = Pattern.compile("^1(?:3\\d{3}|5[^4\\D]\\d{2}|8\\d{3}|7(?:[0-35-9]\\d{2}|4(?:0\\d|1[0-2]|9\\d))|9[0-35-9]\\d{2}|6[2567]\\d{2}|4(?:(?:10|4[01])\\d{3}|[68]\\d{4}|[579]\\d{2}))\\d{6}$"); PATTERN_EMAIL = Pattern.compile("^([a-zA-Z0-9_\\-\\.]+)@((\\[[0-9]{1,3}\\.[0-9]{1,3}\\.[0-9]{1,3}\\.)|(([a-zA-Z0-9\\-]+\\.)+))([a-zA-Z]{2,4}|[0-9]{1,3})(\\]?)$"); PATTERN_ID_CARD = Pattern.compile("(^[1-9]\\d{5}(18|19|([23]\\d))\\d{2}((0[1-9])|(10|11|12))(([0-2][1-9])|10|20|30|31)\\d{3}[0-9Xx]$)|(^[1-9]\\d{5}\\d{2}((0[1-9])|(10|11|12))(([0-2][1-9])|10|20|30|31)\\d{2}$)"); PATTERN_PASSWORD = Pattern.compile("^[0-9a-zA-Z]+$"); From 88959af5a32cb3f6fd71ada2fb4515499d15fba4 Mon Sep 17 00:00:00 2001 From: Rkyzzy <982993741@qq.com> Date: Thu, 20 May 2021 19:44:31 +0800 Subject: [PATCH 04/17] =?UTF-8?q?fix=20=E6=9B=B4=E6=96=B0=E4=BA=86?= =?UTF-8?q?=E6=9C=80=E6=96=B0=E7=9A=84=E6=89=8B=E6=9C=BA=E6=AD=A3=E5=88=99?= =?UTF-8?q?=E8=A1=A8=E8=BE=BE=E5=BC=8F=E5=8C=B9=E9=85=8D=E6=B3=95=E5=88=99?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- APIJSONORM/src/main/java/apijson/StringUtil.java | 1 - 1 file changed, 1 deletion(-) diff --git a/APIJSONORM/src/main/java/apijson/StringUtil.java b/APIJSONORM/src/main/java/apijson/StringUtil.java index 671f04ae0..8d3c32798 100755 --- a/APIJSONORM/src/main/java/apijson/StringUtil.java +++ b/APIJSONORM/src/main/java/apijson/StringUtil.java @@ -311,7 +311,6 @@ public static boolean isNotEmpty(String s, boolean trim) { PATTERN_ALPHA_BIG = Pattern.compile("^[A-Z]+$"); PATTERN_ALPHA_SMALL = Pattern.compile("^[a-z]+$"); PATTERN_NAME = Pattern.compile("^[0-9a-zA-Z_]+$");//已用55个中英字符测试通过 - //PATTERN_PHONE = Pattern.compile("^((13[0-9])|(15[^4,\\D])|(18[0-2,5-9])|(17[0-9]))\\d{8}$"); PATTERN_PHONE = Pattern.compile("^1(?:3\\d{3}|5[^4\\D]\\d{2}|8\\d{3}|7(?:[0-35-9]\\d{2}|4(?:0\\d|1[0-2]|9\\d))|9[0-35-9]\\d{2}|6[2567]\\d{2}|4(?:(?:10|4[01])\\d{3}|[68]\\d{4}|[579]\\d{2}))\\d{6}$"); PATTERN_EMAIL = Pattern.compile("^([a-zA-Z0-9_\\-\\.]+)@((\\[[0-9]{1,3}\\.[0-9]{1,3}\\.[0-9]{1,3}\\.)|(([a-zA-Z0-9\\-]+\\.)+))([a-zA-Z]{2,4}|[0-9]{1,3})(\\]?)$"); PATTERN_ID_CARD = Pattern.compile("(^[1-9]\\d{5}(18|19|([23]\\d))\\d{2}((0[1-9])|(10|11|12))(([0-2][1-9])|10|20|30|31)\\d{3}[0-9Xx]$)|(^[1-9]\\d{5}\\d{2}((0[1-9])|(10|11|12))(([0-2][1-9])|10|20|30|31)\\d{2}$)"); From ebcd7c5f94dbe536b7892408de5030800fc27243 Mon Sep 17 00:00:00 2001 From: Rkyzzy <982993741@qq.com> Date: Thu, 20 May 2021 19:47:44 +0800 Subject: [PATCH 05/17] =?UTF-8?q?fix=20=E6=9B=B4=E6=96=B0=E4=BA=86?= =?UTF-8?q?=E6=9C=80=E6=96=B0=E7=9A=84=E6=89=8B=E6=9C=BA=E5=8F=B7=E6=AD=A3?= =?UTF-8?q?=E5=88=99=E8=A1=A8=E8=BE=BE=E5=BC=8F=E5=8C=B9=E9=85=8D=E6=B3=95?= =?UTF-8?q?=E5=88=99\=20issue=20#240?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- APIJSONORM/src/main/java/apijson/StringUtil.java | 1 + 1 file changed, 1 insertion(+) diff --git a/APIJSONORM/src/main/java/apijson/StringUtil.java b/APIJSONORM/src/main/java/apijson/StringUtil.java index 8d3c32798..9fac4e34e 100755 --- a/APIJSONORM/src/main/java/apijson/StringUtil.java +++ b/APIJSONORM/src/main/java/apijson/StringUtil.java @@ -311,6 +311,7 @@ public static boolean isNotEmpty(String s, boolean trim) { PATTERN_ALPHA_BIG = Pattern.compile("^[A-Z]+$"); PATTERN_ALPHA_SMALL = Pattern.compile("^[a-z]+$"); PATTERN_NAME = Pattern.compile("^[0-9a-zA-Z_]+$");//已用55个中英字符测试通过 + //newest phone regex expression reference https://github.com/VincentSit/ChinaMobilePhoneNumberRegex PATTERN_PHONE = Pattern.compile("^1(?:3\\d{3}|5[^4\\D]\\d{2}|8\\d{3}|7(?:[0-35-9]\\d{2}|4(?:0\\d|1[0-2]|9\\d))|9[0-35-9]\\d{2}|6[2567]\\d{2}|4(?:(?:10|4[01])\\d{3}|[68]\\d{4}|[579]\\d{2}))\\d{6}$"); PATTERN_EMAIL = Pattern.compile("^([a-zA-Z0-9_\\-\\.]+)@((\\[[0-9]{1,3}\\.[0-9]{1,3}\\.[0-9]{1,3}\\.)|(([a-zA-Z0-9\\-]+\\.)+))([a-zA-Z]{2,4}|[0-9]{1,3})(\\]?)$"); PATTERN_ID_CARD = Pattern.compile("(^[1-9]\\d{5}(18|19|([23]\\d))\\d{2}((0[1-9])|(10|11|12))(([0-2][1-9])|10|20|30|31)\\d{3}[0-9Xx]$)|(^[1-9]\\d{5}\\d{2}((0[1-9])|(10|11|12))(([0-2][1-9])|10|20|30|31)\\d{2}$)"); From 494003a9252e6a1c4ca9321940039f96d9b8770e Mon Sep 17 00:00:00 2001 From: TommyLemon <1184482681@qq.com> Date: Thu, 27 May 2021 18:00:02 +0800 Subject: [PATCH 06/17] =?UTF-8?q?=E6=96=B0=E5=A2=9E=E6=96=87=E7=AB=A0=20AP?= =?UTF-8?q?IJSON=E6=95=99=E7=A8=8B=EF=BC=88=E4=B8=80=EF=BC=89=EF=BC=9A?= =?UTF-8?q?=E4=B8=8A=E6=89=8Bapijson=E9=A1=B9=E7=9B=AE=EF=BC=8C=E5=AD=A6?= =?UTF-8?q?=E4=B9=A0apijson=E8=AF=AD=E6=B3=95=EF=BC=8C=E5=B9=B6=E5=AE=9E?= =?UTF-8?q?=E7=8E=B0=E6=8C=81=E4=B9=85=E5=B1=82=E9=85=8D=E7=BD=AE?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit https://zhuanlan.zhihu.com/p/375681893 --- README.md | 2 ++ 1 file changed, 2 insertions(+) diff --git a/README.md b/README.md index 75108017e..952541e0a 100644 --- a/README.md +++ b/README.md @@ -337,6 +337,8 @@ https://github.com/Tencent/APIJSON/blob/master/CONTRIBUTING.md [APIJSON对接分布式HTAP数据库TiDB](https://asktug.com/t/htap-tidb/395) +[APIJSON教程(一):上手apijson项目,学习apijson语法,并实现持久层配置](https://zhuanlan.zhihu.com/p/375681893) + [apijson简单demo](https://blog.csdn.net/dmw412724/article/details/113558115) [apijson简单使用](https://www.cnblogs.com/greyzeng/p/14311995.html) From aecf8f4964887e22118ae7d1c8fa26af2a65bf34 Mon Sep 17 00:00:00 2001 From: TommyLemon <1184482681@qq.com> Date: Mon, 7 Jun 2021 00:16:43 +0800 Subject: [PATCH 07/17] English README: optimize format of request json --- README-English.md | 8 ++++---- 1 file changed, 4 insertions(+), 4 deletions(-) diff --git a/README-English.md b/README-English.md index 9ed377326..68e8ad53f 100644 --- a/README-English.md +++ b/README-English.md @@ -79,7 +79,7 @@ Server developers no longer need to worry about compatibility of APIs and docume #### Get a User Request: -```json +```js { "User":{  } @@ -90,7 +90,7 @@ Request: Response: -```json +```js { "User":{ "id":38710, @@ -116,7 +116,7 @@ Response: Request: -```json +```js { "[]":{   "count":3,             //just get 3 results @@ -131,7 +131,7 @@ Request: Response: -```json +```js { "[]":[ { From fe1e7c783a2cfc3b175039b9a7f3eac94a9535da Mon Sep 17 00:00:00 2001 From: TommyLemon <1184482681@qq.com> Date: Mon, 7 Jun 2021 00:17:53 +0800 Subject: [PATCH 08/17] English README: fix online testing url --- README-English.md | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/README-English.md b/README-English.md index 68e8ad53f..770afb08d 100644 --- a/README-English.md +++ b/README-English.md @@ -160,7 +160,7 @@ Response:
-[Test it online](http://apijson.cn/)
+[Test it online](http://apijson.cn/api)
![](https://raw.githubusercontent.com/TommyLemon/StaticResources/master/APIJSON_Auto_get.jpg) From 1d0146672cd304b966129618d6728ab0b14c4f9f Mon Sep 17 00:00:00 2001 From: TommyLemon <1184482681@qq.com> Date: Mon, 7 Jun 2021 00:25:36 +0800 Subject: [PATCH 09/17] English README: add new contributors --- README-English.md | 9 +++++++++ 1 file changed, 9 insertions(+) diff --git a/README-English.md b/README-English.md index 770afb08d..40ab91fa7 100644 --- a/README-English.md +++ b/README-English.md @@ -331,17 +331,26 @@ Here are the contributers of this project and authors of other projects for ecos height="54" width="54" > + + + + + + + + +
From 41ba66b9fdc85968a2337b224c3dd275f9316d58 Mon Sep 17 00:00:00 2001 From: TommyLemon <1184482681@qq.com> Date: Wed, 9 Jun 2021 22:11:35 +0800 Subject: [PATCH 10/17] Update README.md --- README.md | 5 +++++ 1 file changed, 5 insertions(+) diff --git a/README.md b/README.md index 952541e0a..0083f1814 100644 --- a/README.md +++ b/README.md @@ -129,9 +129,14 @@ APIJSON 是一种专为 API 而生的 JSON 网络传输协议 以及 基于这
### APIJSON 分享演讲 +APIJSON-零代码接口与文档 ORM 库(国际开源谷 Gitee Meetup)
https://www.bilibili.com/video/BV1Tv411t74v ![image](http://apijson.cn/images/comparison/APIJSON_vs_PreviousWays.jpg) +APIJSON和APIAuto-零代码开发和测试(QECon 全球软件质量&效能大会)
+https://www.bilibili.com/video/BV1yv411p7Y4 +wecom-temp-377bbd0daf5aed716baf7ebcb003d94c +
From cdb3bbed9f1c1da14b54108f86748e1b0a6b1a90 Mon Sep 17 00:00:00 2001 From: TommyLemon <1184482681@qq.com> Date: Wed, 9 Jun 2021 22:27:11 +0800 Subject: [PATCH 11/17] =?UTF-8?q?=E5=88=86=E4=BA=AB=E6=BC=94=E8=AE=B2?= =?UTF-8?q?=E6=96=B0=E5=A2=9E=20QECon=20=E5=85=A8=E7=90=83=E8=BD=AF?= =?UTF-8?q?=E4=BB=B6=E8=B4=A8=E9=87=8F&=E6=95=88=E8=83=BD=E5=A4=A7?= =?UTF-8?q?=E4=BC=9A=20=E7=9A=84=E9=9B=B6=E4=BB=A3=E7=A0=81=E5=BC=80?= =?UTF-8?q?=E5=8F=91=E5=92=8C=E6=B5=8B=E8=AF=95?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit https://mp.weixin.qq.com/s/plcRVRcIN_1l59jCigNjhQ --- README.md | 9 +++++++-- 1 file changed, 7 insertions(+), 2 deletions(-) diff --git a/README.md b/README.md index 0083f1814..4ed8b8a29 100644 --- a/README.md +++ b/README.md @@ -129,12 +129,17 @@ APIJSON 是一种专为 API 而生的 JSON 网络传输协议 以及 基于这
### APIJSON 分享演讲 -APIJSON-零代码接口与文档 ORM 库(国际开源谷 Gitee Meetup)
+#### APIJSON-零代码接口与文档 ORM 库(国际开源谷 Gitee Meetup) + https://www.bilibili.com/video/BV1Tv411t74v + ![image](http://apijson.cn/images/comparison/APIJSON_vs_PreviousWays.jpg) -APIJSON和APIAuto-零代码开发和测试(QECon 全球软件质量&效能大会)
+ +#### APIJSON 和 APIAuto-零代码开发和测试(QECon 全球软件质量&效能大会) + https://www.bilibili.com/video/BV1yv411p7Y4 + wecom-temp-377bbd0daf5aed716baf7ebcb003d94c From c4e64759ea4dbf6f11ea8c641ad0998e088e69bc Mon Sep 17 00:00:00 2001 From: jun0315 <1072505283@qq.com> Date: Fri, 11 Jun 2021 13:53:07 +0800 Subject: [PATCH 12/17] feat:log print current time --- APIJSONORM/src/main/java/apijson/Log.java | 43 +++++++++++++++++++---- 1 file changed, 36 insertions(+), 7 deletions(-) diff --git a/APIJSONORM/src/main/java/apijson/Log.java b/APIJSONORM/src/main/java/apijson/Log.java index eecc7e1c2..e3f64f86d 100755 --- a/APIJSONORM/src/main/java/apijson/Log.java +++ b/APIJSONORM/src/main/java/apijson/Log.java @@ -5,20 +5,49 @@ package apijson; +import java.text.SimpleDateFormat; + /**测试用Log * @modifier Lemon */ public class Log { public static boolean DEBUG = true; - + + //默认的时间格式 + public static SimpleDateFormat dateFormat = new SimpleDateFormat("yyyy-MM-dd hh:mm:ss.SSS"); + + /** + * modify date format + * @param dateFormatString + */ + public static void setDateFormat(String dateFormatString) { + dateFormat = new SimpleDateFormat(dateFormatString); + } + + /** + * log info by level tag and msg + * @param TAG + * @param msg + * @param level + */ + public static void logInfo(String TAG, String msg, String level){ + if(level.equals("DEBUG") || level .equals("ERROR") ||level.equals("WARN")){ + System.err.println(dateFormat.format(System.currentTimeMillis()) + ": " + TAG + "." + level + ": " + msg); + } + else if(level.equals("VERBOSE") || level .equals("INFO") ){ + System.out.println(dateFormat.format(System.currentTimeMillis()) + ": " + TAG + "." + level + ": " + msg); + } + } + + /** * @param TAG * @param msg */ public static void d(String TAG, String msg) { if (DEBUG) { - System.err.println(TAG + ".DEBUG: " + msg); + logInfo(TAG,msg,"DEBUG"); } } @@ -28,7 +57,7 @@ public static void d(String TAG, String msg) { * @param msg debug messages */ public static void fd(String TAG, String msg) { - System.err.println(TAG + ".DEBUG: " + msg); + logInfo(TAG,msg,"DEBUG"); } /** @@ -47,7 +76,7 @@ public static void sl(String pre,char symbol ,String post) { */ public static void v(String TAG, String msg) { if (DEBUG) { - System.out.println(TAG + ".VERBOSE: " + msg); + logInfo(TAG,msg,"VERBOSE"); } } @@ -57,7 +86,7 @@ public static void v(String TAG, String msg) { */ public static void i(String TAG, String msg) { if (DEBUG) { - System.out.println(TAG + ".INFO: " + msg); + logInfo(TAG,msg,"INFO"); } } @@ -67,7 +96,7 @@ public static void i(String TAG, String msg) { */ public static void e(String TAG, String msg) { if (DEBUG) { - System.err.println(TAG + ".ERROR: " + msg); + logInfo(TAG,msg,"ERROR"); } } @@ -77,7 +106,7 @@ public static void e(String TAG, String msg) { */ public static void w(String TAG, String msg) { if (DEBUG) { - System.err.println(TAG + ".WARN: " + msg); + logInfo(TAG,msg,"WARN"); } } From 1e1603a97316664a6d4abe384bc9e123f346bfc5 Mon Sep 17 00:00:00 2001 From: TommyLemon <1184482681@qq.com> Date: Fri, 11 Jun 2021 16:30:23 +0800 Subject: [PATCH 13/17] =?UTF-8?q?=E6=96=B0=E5=A2=9E=E4=B8=80=E4=B8=AA?= =?UTF-8?q?=E8=B4=A1=E7=8C=AE=E8=80=85=EF=BC=8C=E6=84=9F=E8=B0=A2=E4=B8=BA?= =?UTF-8?q?=E6=97=A5=E5=BF=97=E6=89=93=E5=8D=B0=E6=96=B0=E5=A2=9E=E5=AF=B9?= =?UTF-8?q?=E5=BA=94=E6=97=B6=E9=97=B4?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit https://github.com/Tencent/APIJSON/pull/250 --- README.md | 1 + 1 file changed, 1 insertion(+) diff --git a/README.md b/README.md index 4ed8b8a29..49ec6ac0b 100644 --- a/README.md +++ b/README.md @@ -261,6 +261,7 @@ https://github.com/Tencent/APIJSON/issues/187 +
Date: Fri, 11 Jun 2021 16:31:48 +0800 Subject: [PATCH 14/17] =?UTF-8?q?=E8=B4=A1=E7=8C=AE=E8=80=85=E5=90=8D?= =?UTF-8?q?=E5=8D=95=E6=96=B0=E5=A2=9E=20jun0315=EF=BC=8C=E6=84=9F?= =?UTF-8?q?=E8=B0=A2=E4=B8=BA=E6=97=A5=E5=BF=97=E6=89=93=E5=8D=B0=E6=96=B0?= =?UTF-8?q?=E5=A2=9E=E5=AF=B9=E5=BA=94=E6=97=B6=E9=97=B4?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit https://github.com/Tencent/APIJSON/pull/250 --- CONTRIBUTING.md | 1 + 1 file changed, 1 insertion(+) diff --git a/CONTRIBUTING.md b/CONTRIBUTING.md index 7613337a3..0c39db52c 100644 --- a/CONTRIBUTING.md +++ b/CONTRIBUTING.md @@ -29,6 +29,7 @@ - [kxlv2000](https://github.com/kxlv2000)(SUSTech) - [caohao-php](https://github.com/caohao-php)(腾讯工程师) - [Wscats](https://github.com/Wscats)(腾讯工程师) +- [jun0315](https://github.com/jun0315) #### 其中特别致谢:
From c0501d0f1e68050d655ffcc46ffd41a82ad80993 Mon Sep 17 00:00:00 2001 From: iceewei Date: Mon, 14 Jun 2021 22:59:40 +0800 Subject: [PATCH 15/17] =?UTF-8?q?=E6=96=B0=E5=A2=9Edatasource=E5=85=B3?= =?UTF-8?q?=E9=94=AE=E5=AD=97?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- .../src/main/java/apijson/JSONObject.java | 27 +++++--- .../apijson/orm/AbstractObjectParser.java | 4 ++ .../main/java/apijson/orm/AbstractParser.java | 15 ++++- .../java/apijson/orm/AbstractSQLConfig.java | 51 ++++++++++++-- .../java/apijson/orm/AbstractVerifier.java | 67 ++++++++++++++++--- .../src/main/java/apijson/orm/Parser.java | 1 + .../src/main/java/apijson/orm/SQLConfig.java | 7 +- 7 files changed, 148 insertions(+), 24 deletions(-) diff --git a/APIJSONORM/src/main/java/apijson/JSONObject.java b/APIJSONORM/src/main/java/apijson/JSONObject.java index 026d63efb..925735bb9 100755 --- a/APIJSONORM/src/main/java/apijson/JSONObject.java +++ b/APIJSONORM/src/main/java/apijson/JSONObject.java @@ -137,9 +137,10 @@ public JSONObject setUserIdIn(List list) { public static final String KEY_ROLE = "@role"; //角色,拥有对某些数据的某些操作的权限 public static final String KEY_DATABASE = "@database"; //数据库类型,默认为MySQL + public static final String KEY_SCHEMA = "@schema"; //数据库,Table在非默认schema内时需要声明 + public static final String KEY_DATASOURCE = "@datasource"; //数据源 public static final String KEY_EXPLAIN = "@explain"; //分析 true/false public static final String KEY_CACHE = "@cache"; //缓存 RAM/ROM/ALL - public static final String KEY_SCHEMA = "@schema"; //数据库,Table在非默认schema内时需要声明 public static final String KEY_COLUMN = "@column"; //查询的Table字段或SQL函数 public static final String KEY_FROM = "@from"; //FROM语句 public static final String KEY_COMBINE = "@combine"; //条件组合,每个条件key前面可以放&,|,!逻辑关系 "id!{},&sex,!name&$" @@ -154,9 +155,10 @@ public JSONObject setUserIdIn(List list) { TABLE_KEY_LIST = new ArrayList(); TABLE_KEY_LIST.add(KEY_ROLE); TABLE_KEY_LIST.add(KEY_DATABASE); + TABLE_KEY_LIST.add(KEY_SCHEMA); + TABLE_KEY_LIST.add(KEY_DATASOURCE); TABLE_KEY_LIST.add(KEY_EXPLAIN); TABLE_KEY_LIST.add(KEY_CACHE); - TABLE_KEY_LIST.add(KEY_SCHEMA); TABLE_KEY_LIST.add(KEY_COLUMN); TABLE_KEY_LIST.add(KEY_FROM); TABLE_KEY_LIST.add(KEY_COMBINE); @@ -216,6 +218,20 @@ public JSONObject setRole(String role) { public JSONObject setDatabase(String database) { return puts(KEY_DATABASE, database); } + /**set schema where table was puts + * @param schema + * @return this + */ + public JSONObject setSchema(String schema) { + return puts(KEY_SCHEMA, schema); + } + /**set datasource where table was puts + * @param datasource + * @return this + */ + public JSONObject setDatasource(String datasource) { + return puts(KEY_DATASOURCE, datasource); + } /**set if return explain informations * @param explain * @return @@ -243,13 +259,6 @@ public JSONObject setCache(Integer cache) { public JSONObject setCache(String cache) { return puts(KEY_CACHE, cache); } - /**set schema where table was puts - * @param schema - * @return this - */ - public JSONObject setSchema(String schema) { - return puts(KEY_SCHEMA, schema); - } /**set keys need to be returned * @param keys key0, key1, key2 ... diff --git a/APIJSONORM/src/main/java/apijson/orm/AbstractObjectParser.java b/APIJSONORM/src/main/java/apijson/orm/AbstractObjectParser.java index f83c9e8bb..5244abc9a 100755 --- a/APIJSONORM/src/main/java/apijson/orm/AbstractObjectParser.java +++ b/APIJSONORM/src/main/java/apijson/orm/AbstractObjectParser.java @@ -287,6 +287,10 @@ else if (method == PUT && value instanceof JSONArray if (parser.getGlobleSchema() != null && sqlRequest.get(JSONRequest.KEY_SCHEMA) == null) { sqlRequest.put(JSONRequest.KEY_SCHEMA, parser.getGlobleSchema()); } + if (parser.getGlobleDatasource() != null && sqlRequest.get(JSONRequest.KEY_DATASOURCE) == null) { + sqlRequest.put(JSONRequest.KEY_DATASOURCE, parser.getGlobleDatasource()); + } + if (isSubquery == false) { //解决 SQL 语法报错,子查询不能 EXPLAIN if (parser.getGlobleExplain() != null && sqlRequest.get(JSONRequest.KEY_EXPLAIN) == null) { sqlRequest.put(JSONRequest.KEY_EXPLAIN, parser.getGlobleExplain()); diff --git a/APIJSONORM/src/main/java/apijson/orm/AbstractParser.java b/APIJSONORM/src/main/java/apijson/orm/AbstractParser.java index c46e82e4e..84bbca2b7 100755 --- a/APIJSONORM/src/main/java/apijson/orm/AbstractParser.java +++ b/APIJSONORM/src/main/java/apijson/orm/AbstractParser.java @@ -199,6 +199,16 @@ public AbstractParser setGlobleSchema(String globleSchema) { public String getGlobleSchema() { return globleSchema; } + protected String globleDatasource; + @Override + public String getGlobleDatasource() { + return globleDatasource; + } + public AbstractParser setGlobleDatasource(String globleDatasource) { + this.globleDatasource = globleDatasource; + return this; + } + protected Boolean globleExplain; public AbstractParser setGlobleExplain(Boolean globleExplain) { this.globleExplain = globleExplain; @@ -361,12 +371,14 @@ public JSONObject parseResponse(JSONObject request) { setGlobleFormat(requestObject.getBoolean(JSONRequest.KEY_FORMAT)); setGlobleDatabase(requestObject.getString(JSONRequest.KEY_DATABASE)); setGlobleSchema(requestObject.getString(JSONRequest.KEY_SCHEMA)); + setGlobleDatasource(requestObject.getString(JSONRequest.KEY_DATASOURCE)); setGlobleExplain(requestObject.getBoolean(JSONRequest.KEY_EXPLAIN)); setGlobleCache(requestObject.getString(JSONRequest.KEY_CACHE)); requestObject.remove(JSONRequest.KEY_FORMAT); requestObject.remove(JSONRequest.KEY_DATABASE); requestObject.remove(JSONRequest.KEY_SCHEMA); + requestObject.remove(JSONRequest.KEY_DATASOURCE); requestObject.remove(JSONRequest.KEY_EXPLAIN); requestObject.remove(JSONRequest.KEY_CACHE); } catch (Exception e) { @@ -1245,6 +1257,7 @@ else if (join != null){ JOIN_COPY_KEY_LIST.add(JSONRequest.KEY_ROLE); JOIN_COPY_KEY_LIST.add(JSONRequest.KEY_DATABASE); JOIN_COPY_KEY_LIST.add(JSONRequest.KEY_SCHEMA); + JOIN_COPY_KEY_LIST.add(JSONRequest.KEY_DATASOURCE); JOIN_COPY_KEY_LIST.add(JSONRequest.KEY_COLUMN); JOIN_COPY_KEY_LIST.add(JSONRequest.KEY_COMBINE); JOIN_COPY_KEY_LIST.add(JSONRequest.KEY_GROUP); @@ -1464,7 +1477,7 @@ public Object getValueByPath(String valuePath) { //取出key被valuePath包含的result,再从里面获取key对应的value JSONObject parent = null; String[] keys = null; - for (Map.Entry entry : queryResultMap.entrySet()){ + for (Entry entry : queryResultMap.entrySet()){ String path = entry.getKey(); if (valuePath.startsWith(path + "/")) { try { diff --git a/APIJSONORM/src/main/java/apijson/orm/AbstractSQLConfig.java b/APIJSONORM/src/main/java/apijson/orm/AbstractSQLConfig.java index efedbe3e8..d963fea55 100755 --- a/APIJSONORM/src/main/java/apijson/orm/AbstractSQLConfig.java +++ b/APIJSONORM/src/main/java/apijson/orm/AbstractSQLConfig.java @@ -9,6 +9,7 @@ import static apijson.JSONObject.KEY_COLUMN; import static apijson.JSONObject.KEY_COMBINE; import static apijson.JSONObject.KEY_DATABASE; +import static apijson.JSONObject.KEY_DATASOURCE; import static apijson.JSONObject.KEY_EXPLAIN; import static apijson.JSONObject.KEY_FROM; import static apijson.JSONObject.KEY_GROUP; @@ -335,6 +336,7 @@ public String getUserIdKey() { private boolean distinct = false; private String database; //表所在的数据库类型 private String schema; //表所在的数据库名 + private String datasource; //数据源 private String table; //表名 private String alias; //表别名 private String group; //分组方式的字符串数组,','分隔 @@ -549,6 +551,17 @@ public AbstractSQLConfig setSchema(String schema) { this.schema = schema; return this; } + + @Override + public String getDatasource() { + return datasource; + } + @Override + public SQLConfig setDatasource(String datasource) { + this.datasource = datasource; + return this; + } + /**请求传进来的Table名 * @return * @see {@link #getSQLTable()} @@ -1547,7 +1560,7 @@ public Object getWhere(String key, boolean exactMatch) { synchronized (where) { if (where != null) { int index; - for (Map.Entry entry : where.entrySet()) { + for (Entry entry : where.entrySet()) { String k = entry.getKey(); index = k.indexOf(key); if (index >= 0 && StringUtil.isName(k.substring(index)) == false) { @@ -2502,7 +2515,7 @@ public String getSetString(RequestMethod method, Map content, bo Object value; String idKey = getIdKey(); - for (Map.Entry entry : content.entrySet()) { + for (Entry entry : content.entrySet()) { String key = entry.getKey(); //避免筛选到全部 value = key == null ? null : content.get(key); if (key == null || idKey.equals(key)) { @@ -2811,12 +2824,14 @@ public static SQLConfig newSQLConfig(RequestMethod method, String table, String } String schema = request.getString(KEY_SCHEMA); + String datasource = request.getString(KEY_DATASOURCE); SQLConfig config = callback.getSQLConfig(method, database, schema, table); config.setAlias(alias); config.setDatabase(database); //不删,后面表对象还要用的,必须放在 parseJoin 前 config.setSchema(schema); //不删,后面表对象还要用的 + config.setDatasource(datasource); //不删,后面表对象还要用的 if (isProcedure) { return config; @@ -3387,21 +3402,39 @@ public static interface IdCallback { */ Object newId(RequestMethod method, String database, String schema, String table); - /**获取主键名 + /**已废弃,最早 5.0.0 移除,改用 {@link #getIdKey(String, String, String, String)} * @param database * @param schema * @param table * @return */ + @Deprecated String getIdKey(String database, String schema, String table); + + /**获取主键名 + * @param database + * @param schema + * @param table + * @return + */ + String getIdKey(String database, String schema, String datasource, String table); - /**获取 User 的主键名 + /**已废弃,最早 5.0.0 移除,改用 {@link #getUserIdKey(String, String, String, String)} * @param database * @param schema * @param table * @return */ + @Deprecated String getUserIdKey(String database, String schema, String table); + + /**获取 User 的主键名 + * @param database + * @param schema + * @param table + * @return + */ + String getUserIdKey(String database, String schema, String datasource, String table); } public static interface Callback extends IdCallback { @@ -3434,11 +3467,21 @@ public Object newId(RequestMethod method, String database, String schema, String public String getIdKey(String database, String schema, String table) { return KEY_ID; } + + @Override + public String getIdKey(String database, String schema, String datasource, String table) { + return getIdKey(database, schema, table); + } @Override public String getUserIdKey(String database, String schema, String table) { return KEY_USER_ID; } + + @Override + public String getUserIdKey(String database, String schema, String datasource, String table) { + return getUserIdKey(database, schema, table); + } @Override public void onMissingKey4Combine(String name, JSONObject request, String combine, String item, String key) throws Exception { diff --git a/APIJSONORM/src/main/java/apijson/orm/AbstractVerifier.java b/APIJSONORM/src/main/java/apijson/orm/AbstractVerifier.java index 926a037f8..30aeb5f15 100755 --- a/APIJSONORM/src/main/java/apijson/orm/AbstractVerifier.java +++ b/APIJSONORM/src/main/java/apijson/orm/AbstractVerifier.java @@ -109,8 +109,8 @@ public abstract class AbstractVerifier implements Verifier, IdCallback { OPERATION_KEY_LIST.add(REMOVE.name()); OPERATION_KEY_LIST.add(MUST.name()); OPERATION_KEY_LIST.add(REFUSE.name()); - - + + SYSTEM_ACCESS_MAP = new HashMap>(); SYSTEM_ACCESS_MAP.put(Access.class.getSimpleName(), getAccessMap(Access.class.getAnnotation(MethodAccess.class))); @@ -170,10 +170,18 @@ public String getIdKey(String database, String schema, String table) { return apijson.JSONObject.KEY_ID; } @Override + public String getIdKey(String database, String schema, String datasource, String table) { + return getIdKey(database, schema, table); + } + @Override public String getUserIdKey(String database, String schema, String table) { return apijson.JSONObject.KEY_USER_ID; } @Override + public String getUserIdKey(String database, String schema, String datasource, String table) { + return getUserIdKey(database, schema, table); + } + @Override public Object newId(RequestMethod method, String database, String schema, String table) { return System.currentTimeMillis(); } @@ -515,6 +523,23 @@ public static JSONObject verifyRequest(@NotNull final RequestMethod method, fina public static JSONObject verifyRequest(@NotNull final RequestMethod method, final String name , final JSONObject target, final JSONObject request, final int maxUpdateCount , final String database, final String schema, final IdCallback idCallback, final SQLCreator creator) throws Exception { + return verifyRequest(method, name, target, request, maxUpdateCount, database, schema, null, idCallback, creator); + } + /**从request提取target指定的内容 + * @param method + * @param name + * @param target + * @param request + * @param maxUpdateCount + * @param idKey + * @param userIdKey + * @param creator + * @return + * @throws Exception + */ + public static JSONObject verifyRequest(@NotNull final RequestMethod method, final String name + , final JSONObject target, final JSONObject request, final int maxUpdateCount + , final String database, final String schema, final String datasource, final IdCallback idCallback, final SQLCreator creator) throws Exception { Log.i(TAG, "verifyRequest method = " + method + "; name = " + name + "; target = \n" + JSON.toJSONString(target) @@ -546,14 +571,18 @@ public JSONObject onParseJSONObject(String key, JSONObject tobj, JSONObject robj } else if (apijson.JSONObject.isTableKey(key)) { String db = request.getString(apijson.JSONObject.KEY_DATABASE); String sh = request.getString(apijson.JSONObject.KEY_SCHEMA); + String ds = request.getString(apijson.JSONObject.KEY_DATASOURCE); if (StringUtil.isEmpty(db, false)) { db = database; } if (StringUtil.isEmpty(sh, false)) { sh = schema; } + if (StringUtil.isEmpty(ds, false)) { + ds = datasource; + } - String idKey = idCallback == null ? null : idCallback.getIdKey(db, sh, key); + String idKey = idCallback == null ? null : idCallback.getIdKey(db, sh, ds, key); String finalIdKey = StringUtil.isEmpty(idKey, false) ? apijson.JSONObject.KEY_ID : idKey; if (method == RequestMethod.POST) { @@ -564,7 +593,7 @@ public JSONObject onParseJSONObject(String key, JSONObject tobj, JSONObject robj if (RequestMethod.isQueryMethod(method) == false) { verifyId(method.name(), name, key, robj, finalIdKey, maxUpdateCount, true); - String userIdKey = idCallback == null ? null : idCallback.getUserIdKey(db, sh, key); + String userIdKey = idCallback == null ? null : idCallback.getUserIdKey(db, sh, ds, key); String finalUserIdKey = StringUtil.isEmpty(userIdKey, false) ? apijson.JSONObject.KEY_USER_ID : userIdKey; verifyId(method.name(), name, key, robj, finalUserIdKey, maxUpdateCount, false); } @@ -742,14 +771,14 @@ public static JSONObject parse(@NotNull final RequestMethod method, String name, , SQLCreator creator, @NotNull OnParseCallback callback) throws Exception { return parse(method, name, target, real, null, null, null, creator, callback); } - /**对request和response不同的解析用callback返回 * @param method * @param name * @param target * @param real - * @param idKey - * @param userIdKey + * @param database + * @param schema + * @param idCallback * @param creator * @param callback * @return @@ -757,6 +786,24 @@ public static JSONObject parse(@NotNull final RequestMethod method, String name, */ public static JSONObject parse(@NotNull final RequestMethod method, String name, JSONObject target, JSONObject real , final String database, final String schema, final IdCallback idCallback, SQLCreator creator, @NotNull OnParseCallback callback) throws Exception { + return parse(method, name, target, real, database, schema, null, idCallback, creator, callback); + } + /**对request和response不同的解析用callback返回 + * @param method + * @param name + * @param target + * @param real + * @param database + * @param schema + * @param datasource + * @param idCallback + * @param creator + * @param callback + * @return + * @throws Exception + */ + public static JSONObject parse(@NotNull final RequestMethod method, String name, JSONObject target, JSONObject real + , final String database, final String schema, final String datasource, final IdCallback idCallback, SQLCreator creator, @NotNull OnParseCallback callback) throws Exception { if (target == null) { return null; } @@ -913,12 +960,16 @@ public static JSONObject parse(@NotNull final RequestMethod method, String name, String db = real.getString(apijson.JSONObject.KEY_DATABASE); String sh = real.getString(apijson.JSONObject.KEY_SCHEMA); + String ds = real.getString(apijson.JSONObject.KEY_DATASOURCE); if (StringUtil.isEmpty(db, false)) { db = database; } if (StringUtil.isEmpty(sh, false)) { sh = schema; } + if (StringUtil.isEmpty(ds, false)) { + ds = datasource; + } String idKey = idCallback == null ? null : idCallback.getIdKey(db, sh, name); String finalIdKey = StringUtil.isEmpty(idKey, false) ? apijson.JSONObject.KEY_ID : idKey; @@ -977,7 +1028,7 @@ private static JSONObject operate(Operation opt, JSONObject targetChild, JSONObj if (tk == null || OPERATION_KEY_LIST.contains(tk)) { continue; } - + tv = e.getValue(); if (opt == TYPE) { diff --git a/APIJSONORM/src/main/java/apijson/orm/Parser.java b/APIJSONORM/src/main/java/apijson/orm/Parser.java index dee098b29..6e0af5368 100755 --- a/APIJSONORM/src/main/java/apijson/orm/Parser.java +++ b/APIJSONORM/src/main/java/apijson/orm/Parser.java @@ -124,6 +124,7 @@ JSONObject parseCorrectRequest(RequestMethod method, String tag, int version, St RequestRole getGlobleRole(); String getGlobleDatabase(); String getGlobleSchema(); + String getGlobleDatasource(); Boolean getGlobleExplain(); String getGlobleCache(); diff --git a/APIJSONORM/src/main/java/apijson/orm/SQLConfig.java b/APIJSONORM/src/main/java/apijson/orm/SQLConfig.java index 7e73bdd18..9abce83b9 100755 --- a/APIJSONORM/src/main/java/apijson/orm/SQLConfig.java +++ b/APIJSONORM/src/main/java/apijson/orm/SQLConfig.java @@ -120,10 +120,13 @@ public interface SQLConfig { String getDatabase(); SQLConfig setDatabase(String database); - String getQuote(); - String getSchema(); SQLConfig setSchema(String schema); + + String getDatasource(); + SQLConfig setDatasource(String datasource); + + String getQuote(); /**请求传进来的Table名 * @return From b1b814ec48f2fe801d4762b94b809858f6b3621e Mon Sep 17 00:00:00 2001 From: TommyLemon <1184482681@qq.com> Date: Tue, 15 Jun 2021 00:03:02 +0800 Subject: [PATCH 16/17] =?UTF-8?q?=E5=88=86=E9=A1=B5=EF=BC=9A=E8=A7=A3?= =?UTF-8?q?=E5=86=B3=20query=3D2=20=E4=B8=8D=E5=85=BC=E5=AE=B9=20=E4=B8=BB?= =?UTF-8?q?=E8=A1=A8=20@column:"fun()"=20=E8=BF=99=E7=A7=8D=E5=8C=85?= =?UTF-8?q?=E5=90=AB=20SQL=20=E5=87=BD=E6=95=B0=E7=9A=84=E5=86=99=E6=B3=95?= =?UTF-8?q?=EF=BC=9BSQL=20=E5=87=BD=E6=95=B0=EF=BC=9A=E8=8E=B7=E5=8F=96?= =?UTF-8?q?=E5=8F=B3=E6=8B=AC=E5=8F=B7=20)=20=E7=9A=84=E4=BD=8D=E7=BD=AE?= =?UTF-8?q?=E4=BB=8E=20=20indexOf=20=E6=94=B9=E4=B8=BA=20lastIndexOf?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- .../java/apijson/orm/AbstractSQLConfig.java | 29 ++++++++++++++----- 1 file changed, 22 insertions(+), 7 deletions(-) diff --git a/APIJSONORM/src/main/java/apijson/orm/AbstractSQLConfig.java b/APIJSONORM/src/main/java/apijson/orm/AbstractSQLConfig.java index d963fea55..758b49cbd 100755 --- a/APIJSONORM/src/main/java/apijson/orm/AbstractSQLConfig.java +++ b/APIJSONORM/src/main/java/apijson/orm/AbstractSQLConfig.java @@ -768,7 +768,7 @@ public String getHavingString(boolean hasPrefix) { continue; } - int end = expression.indexOf(")"); + int end = expression.lastIndexOf(")"); if (start >= end) { throw new IllegalArgumentException("字符 " + expression + " 不合法!" + "@having:value 中 value 里的 SQL函数必须为 function(arg0,arg1,...) 这种格式!"); @@ -1040,13 +1040,28 @@ public String getColumnString(boolean inSQLJoin) throws Exception { index = c.lastIndexOf(":"); //StringUtil.split返回数组中,子项不会有null origin = index < 0 ? c : c.substring(0, index); alias = index < 0 ? null : c.substring(index + 1); - if (StringUtil.isName(origin) == false || (alias != null && StringUtil.isName(alias) == false)) { - throw new IllegalArgumentException("HEAD请求: 预编译模式下 @column:value 中 value里面用 , 分割的每一项" + + if (alias != null && StringUtil.isName(alias) == false) { + throw new IllegalArgumentException("HEAD请求: 字符 " + alias + " 不合法!预编译模式下 @column:value 中 value里面用 , 分割的每一项" + " column:alias 中 column 必须是1个单词!如果有alias,则alias也必须为1个单词!并且不要有多余的空格!"); } + + if (StringUtil.isName(origin) == false) { + int start = origin.indexOf("("); + if (start < 0 || origin.lastIndexOf(")") <= start) { + throw new IllegalArgumentException("HEAD请求: 字符" + origin + " 不合法!预编译模式下 @column:value 中 value里面用 , 分割的每一项" + + " column:alias 中 column 必须是1个单词!如果有alias,则alias也必须为1个单词!并且不要有多余的空格!"); + } + + if (start > 0 && StringUtil.isName(origin.substring(0, start)) == false) { + throw new IllegalArgumentException("HEAD请求: 字符 " + origin.substring(0, start) + " 不合法!预编译模式下 @column:value 中 value里面用 , 分割的每一项" + + " column:alias 中 column 必须是1个单词!如果有alias,则alias也必须为1个单词!并且不要有多余的空格!"); + } + } } } - return SQL.count(column != null && column.size() == 1 ? getKey(Pair.parseEntry(column.get(0), true).getKey()) : "*"); + + return SQL.count(column != null && column.size() == 1 && StringUtil.isName(column.get(0)) ? getKey(column.get(0)) : "*"); case POST: if (column == null || column.isEmpty()) { throw new IllegalArgumentException("POST 请求必须在Table内设置要保存的 key:value !"); @@ -1151,7 +1166,7 @@ public String getColumnString(boolean inSQLJoin) throws Exception { int start = expression.indexOf("("); int end = 0; if (start >= 0) { - end = expression.indexOf(")"); + end = expression.lastIndexOf(")"); if (start >= end) { throw new IllegalArgumentException("字符 " + expression + " 不合法!" + "@column:value 中 value 里的 SQL函数必须为 function(arg0,arg1,...) 这种格式!"); @@ -2254,7 +2269,7 @@ else if (range instanceof String) {//非Number类型需要客户端拼接成 < ' if (rawSQL != null) { int index = rawSQL == null ? -1 : rawSQL.indexOf("("); - condition = (index >= 0 && index < rawSQL.indexOf(")") ? "" : getKey(k) + " ") + rawSQL; + condition = (index >= 0 && index < rawSQL.lastIndexOf(")") ? "" : getKey(k) + " ") + rawSQL; } // 还是只支持整段为 Raw SQL 比较好 @@ -2299,7 +2314,7 @@ else if (isPrepared() && (c.contains("--") || PATTERN_RANGE.matcher(c).matches() index = c == null ? -1 : c.indexOf("("); condition += ((i <= 0 ? "" : (logic.isAnd() ? AND : OR)) //连接方式 - + (index >= 0 && index < c.indexOf(")") ? "" : getKey(k) + " ") //函数和非函数条件 + + (index >= 0 && index < c.lastIndexOf(")") ? "" : getKey(k) + " ") //函数和非函数条件 + c); // 还是只支持整段为 Raw SQL 比较好 (appendRaw && index > 0 ? rawSQL : "") + c); //单个条件,如果有 Raw SQL 则按原来位置拼接 } } From 175bd81a41a4a8beca30dbfc6858f40caf83d389 Mon Sep 17 00:00:00 2001 From: TommyLemon <1184482681@qq.com> Date: Tue, 15 Jun 2021 00:51:16 +0800 Subject: [PATCH 17/17] =?UTF-8?q?=E5=88=86=E9=A1=B5:=20=E5=9C=A8=E5=88=86?= =?UTF-8?q?=E9=A1=B5=E8=AF=A6=E6=83=85=20info=20=E5=86=85=E8=BF=94?= =?UTF-8?q?=E5=9B=9E=E6=9F=A5=E8=AF=A2=E8=AE=A1=E5=88=92=20@explain?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- .../main/java/apijson/orm/AbstractParser.java | 5 + .../java/apijson/orm/AbstractSQLConfig.java | 11 +- .../java/apijson/orm/AbstractSQLExecutor.java | 173 +++++++++--------- 3 files changed, 100 insertions(+), 89 deletions(-) diff --git a/APIJSONORM/src/main/java/apijson/orm/AbstractParser.java b/APIJSONORM/src/main/java/apijson/orm/AbstractParser.java index 84bbca2b7..7051b3e06 100755 --- a/APIJSONORM/src/main/java/apijson/orm/AbstractParser.java +++ b/APIJSONORM/src/main/java/apijson/orm/AbstractParser.java @@ -871,6 +871,10 @@ public JSONObject onObjectParse(final JSONObject request } JSONObject pagination = new JSONObject(true); + Object explain = rp.get(JSONResponse.KEY_EXPLAIN); + if (explain instanceof JSONObject) { + pagination.put(JSONResponse.KEY_EXPLAIN, explain); + } pagination.put(JSONResponse.KEY_TOTAL, total); pagination.put(JSONRequest.KEY_COUNT, count); pagination.put(JSONRequest.KEY_PAGE, page); @@ -878,6 +882,7 @@ public JSONObject onObjectParse(final JSONObject request pagination.put(JSONResponse.KEY_MORE, page < max); pagination.put(JSONResponse.KEY_FIRST, page == 0); pagination.put(JSONResponse.KEY_LAST, page == max); + putQueryResult(pathPrefix + JSONResponse.KEY_INFO, pagination); if (total <= count*page) { diff --git a/APIJSONORM/src/main/java/apijson/orm/AbstractSQLConfig.java b/APIJSONORM/src/main/java/apijson/orm/AbstractSQLConfig.java index 758b49cbd..2eabffc62 100755 --- a/APIJSONORM/src/main/java/apijson/orm/AbstractSQLConfig.java +++ b/APIJSONORM/src/main/java/apijson/orm/AbstractSQLConfig.java @@ -2647,12 +2647,13 @@ public static String getSQL(AbstractSQLConfig config) throws Exception { config.setPreparedValueList(new ArrayList()); String column = config.getColumnString(); - if(config.isOracle()){ + if (config.isOracle()) { //When config's database is oracle,Using subquery since Oracle12 below does not support OFFSET FETCH paging syntax. - return explain + "SELECT * FROM (SELECT"+ (config.getCache() == JSONRequest.CACHE_RAM ? "SQL_NO_CACHE " : "") + column + " FROM "+getConditionString(column, tablePath, config)+ ") "+config.getLimitString(); - }else - return explain + "SELECT " + (config.getCache() == JSONRequest.CACHE_RAM ? "SQL_NO_CACHE " : "") + column + " FROM " + getConditionString(column, tablePath, config); + return explain + "SELECT * FROM (SELECT"+ (config.getCache() == JSONRequest.CACHE_RAM ? "SQL_NO_CACHE " : "") + column + " FROM " + getConditionString(column, tablePath, config) + ") " + config.getLimitString(); } + + return explain + "SELECT " + (config.getCache() == JSONRequest.CACHE_RAM ? "SQL_NO_CACHE " : "") + column + " FROM " + getConditionString(column, tablePath, config) + config.getLimitString(); + } } /**获取条件SQL字符串 @@ -2679,7 +2680,7 @@ private static String getConditionString(String column, String table, AbstractSQ //no need to optimize // if (config.getPage() <= 0 || ID.equals(column.trim())) { - return config.isOracle()? condition:condition + config.getLimitString(); + return condition; // config.isOracle() ? condition : condition + config.getLimitString(); // } // // diff --git a/APIJSONORM/src/main/java/apijson/orm/AbstractSQLExecutor.java b/APIJSONORM/src/main/java/apijson/orm/AbstractSQLExecutor.java index 6008c4b13..15b178be4 100755 --- a/APIJSONORM/src/main/java/apijson/orm/AbstractSQLExecutor.java +++ b/APIJSONORM/src/main/java/apijson/orm/AbstractSQLExecutor.java @@ -148,21 +148,24 @@ public ResultSet execute(@NotNull Statement statement, String sql) throws Except */ @Override public JSONObject execute(@NotNull SQLConfig config, boolean unknowType) throws Exception { - boolean prepared = config.isPrepared(); + boolean isPrepared = config.isPrepared(); final String sql = config.getSQL(false); - config.setPrepared(prepared); + config.setPrepared(isPrepared); if (StringUtil.isEmpty(sql, true)) { Log.e(TAG, "execute StringUtil.isEmpty(sql, true) >> return null;"); return null; } + + boolean isExplain = config.isExplain(); + boolean isHead = RequestMethod.isHeadMethod(config.getMethod(), true); final int position = config.getPosition(); JSONObject result; - if (config.isExplain() == false) { + if (isExplain == false) { generatedSQLCount ++; } @@ -192,17 +195,6 @@ public JSONObject execute(@NotNull SQLConfig config, boolean unknowType) throws } else { switch (config.getMethod()) { - case HEAD: - case HEADS: - rs = executeQuery(config); - - executedSQLCount ++; - - result = rs.next() ? AbstractParser.newSuccessResult() - : AbstractParser.newErrorResult(new SQLException("数据库错误, rs.next() 失败!")); - result.put(JSONResponse.KEY_COUNT, rs.getLong(1)); - return result; - case POST: case PUT: case DELETE: @@ -224,10 +216,12 @@ public JSONObject execute(@NotNull SQLConfig config, boolean unknowType) throws result.put(config.getIdKey() + "[]", config.getWhere(config.getIdKey() + "{}", true)); } return result; - + case GET: case GETS: - result = getCacheItem(sql, position, config.getCache()); + case HEAD: + case HEADS: + result = isHead ? null : getCacheItem(sql, position, config.getCache()); Log.i(TAG, ">>> execute result = getCache('" + sql + "', " + position + ") = " + result); if (result != null) { cachedSQLCount ++; @@ -238,7 +232,7 @@ public JSONObject execute(@NotNull SQLConfig config, boolean unknowType) throws rs = executeQuery(config); //FIXME SQL Server 是一次返回两个结果集,包括查询结果和执行计划,需要 moreResults - if (config.isExplain() == false) { //只有 SELECT 才能 EXPLAIN + if (isExplain == false) { //只有 SELECT 才能 EXPLAIN executedSQLCount ++; } break; @@ -249,58 +243,68 @@ public JSONObject execute(@NotNull SQLConfig config, boolean unknowType) throws } } + + if (isExplain == false && isHead) { + if (rs.next() == false) { + return AbstractParser.newErrorResult(new SQLException("数据库错误, rs.next() 失败!")); + } + result = AbstractParser.newSuccessResult(); + result.put(JSONResponse.KEY_COUNT, rs.getLong(1)); + resultList = new ArrayList<>(1); + resultList.add(result); + } + else { + // final boolean cache = config.getCount() != 1; + // TODO 设置初始容量为查到的数据量,解决频繁扩容导致的延迟,貌似只有 rs.last 取 rs.getRow() ? 然后又得 rs.beforeFirst 重置位置以便下方取值 + resultList = new ArrayList<>(config.getCount() <= 0 ? Parser.MAX_QUERY_COUNT : config.getCount()); + // Log.d(TAG, "select cache = " + cache + "; resultList" + (resultList == null ? "=" : "!=") + "null"); - // final boolean cache = config.getCount() != 1; - // TODO 设置初始容量为查到的数据量,解决频繁扩容导致的延迟,貌似只有 rs.last 取 rs.getRow() ? 然后又得 rs.beforeFirst 重置位置以便下方取值 - resultList = new ArrayList<>(config.getCount() <= 0 ? Parser.MAX_QUERY_COUNT : config.getCount()); - // Log.d(TAG, "select cache = " + cache + "; resultList" + (resultList == null ? "=" : "!=") + "null"); - - int index = -1; + int index = -1; - ResultSetMetaData rsmd = rs.getMetaData(); - final int length = rsmd.getColumnCount(); + ResultSetMetaData rsmd = rs.getMetaData(); + final int length = rsmd.getColumnCount(); - // + childMap = new HashMap<>(); //要存到cacheMap + // WHERE id = ? AND ... 或 WHERE ... AND id = ? 强制排序 remove 再 put,还是重新 getSQL吧 - boolean hasJoin = config.hasJoin(); - int viceColumnStart = length + 1; //第一个副表字段的index - while (rs.next()) { - index ++; - Log.d(TAG, "\n\n<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<\n execute while (rs.next()){ index = " + index + "\n\n"); + boolean hasJoin = config.hasJoin(); + int viceColumnStart = length + 1; //第一个副表字段的index + while (rs.next()) { + index ++; + Log.d(TAG, "\n\n<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<\n execute while (rs.next()){ index = " + index + "\n\n"); - JSONObject item = new JSONObject(true); + JSONObject item = new JSONObject(true); - for (int i = 1; i <= length; i++) { + for (int i = 1; i <= length; i++) { - // if (hasJoin && viceColumnStart > length && config.getSQLTable().equalsIgnoreCase(rsmd.getTableName(i)) == false) { - // viceColumnStart = i; - // } + // if (hasJoin && viceColumnStart > length && config.getSQLTable().equalsIgnoreCase(rsmd.getTableName(i)) == false) { + // viceColumnStart = i; + // } - // bugfix-修复非常规数据库字段,获取表名失败导致输出异常 - if (config.isExplain() == false && hasJoin && viceColumnStart > length) { - List column = config.getColumn(); + // bugfix-修复非常规数据库字段,获取表名失败导致输出异常 + if (isExplain == false && hasJoin && viceColumnStart > length) { + List column = config.getColumn(); - if (column != null && column.isEmpty() == false) { - viceColumnStart = column.size() + 1; - } - else if (config.getSQLTable().equalsIgnoreCase(rsmd.getTableName(i)) == false) { - viceColumnStart = i; + if (column != null && column.isEmpty() == false) { + viceColumnStart = column.size() + 1; + } + else if (config.getSQLTable().equalsIgnoreCase(rsmd.getTableName(i)) == false) { + viceColumnStart = i; + } } - } - item = onPutColumn(config, rs, rsmd, index, item, i, config.isExplain() == false && hasJoin && i >= viceColumnStart ? childMap : null); - } + item = onPutColumn(config, rs, rsmd, index, item, i, isExplain == false && hasJoin && i >= viceColumnStart ? childMap : null); + } - resultList = onPutTable(config, rs, rsmd, resultList, index, item); + resultList = onPutTable(config, rs, rsmd, resultList, index, item); - Log.d(TAG, "\n execute while (rs.next()) { resultList.put( " + index + ", result); " - + "\n >>>>>>>>>>>>>>>>>>>>>>>>>>> \n\n"); + Log.d(TAG, "\n execute while (rs.next()) { resultList.put( " + index + ", result); " + + "\n >>>>>>>>>>>>>>>>>>>>>>>>>>> \n\n"); + } } - } finally { if (rs != null) { @@ -317,50 +321,51 @@ else if (config.getSQLTable().equalsIgnoreCase(rsmd.getTableName(i)) == false) { return null; } - if (unknowType || config.isExplain()) { - if (config.isExplain()) { + if (unknowType || isExplain) { + if (isExplain) { if (result == null) { result = new JSONObject(true); } - boolean explain = config.isExplain(); config.setExplain(false); result.put("sql", config.getSQL(false)); - config.setExplain(explain); - config.setPrepared(prepared); + config.setExplain(isExplain); + config.setPrepared(isPrepared); } result.put("list", resultList); return result; } + + if (isHead == false) { + // @ APP JOIN 查询副表并缓存到 childMap <<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<< - // @ APP JOIN 查询副表并缓存到 childMap <<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<< + executeAppJoin(config, resultList, childMap); - executeAppJoin(config, resultList, childMap); + // @ APP JOIN 查询副表并缓存到 childMap >>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>> - // @ APP JOIN 查询副表并缓存到 childMap >>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>> + //子查询 SELECT Moment.*, Comment.id 中的 Comment 内字段 + Set> set = childMap.entrySet(); - //子查询 SELECT Moment.*, Comment.id 中的 Comment 内字段 - Set> set = childMap.entrySet(); + // + for (Entry entry : set) { + List l = new ArrayList<>(); + l.add(entry.getValue()); + putCache(entry.getKey(), l, JSONRequest.CACHE_ROM); + } - // - for (Entry entry : set) { - List l = new ArrayList<>(); - l.add(entry.getValue()); - putCache(entry.getKey(), l, JSONRequest.CACHE_ROM); - } + putCache(sql, resultList, config.getCache()); + Log.i(TAG, ">>> execute putCache('" + sql + "', resultList); resultList.size() = " + resultList.size()); - putCache(sql, resultList, config.getCache()); - Log.i(TAG, ">>> execute putCache('" + sql + "', resultList); resultList.size() = " + resultList.size()); + // 数组主表对象额外一次返回全部,方便 Parser 缓存来提高性能 - // 数组主表对象额外一次返回全部,方便 Parser 缓存来提高性能 - - result = position >= resultList.size() ? new JSONObject() : resultList.get(position); - if (position == 0 && resultList.size() > 1 && result != null && result.isEmpty() == false) { - // 不是 main 不会直接执行,count=1 返回的不会超过 1 && config.isMain() && config.getCount() != 1 - Log.i(TAG, ">>> execute position == 0 && resultList.size() > 1 && result != null && result.isEmpty() == false" - + " >> result = new JSONObject(result); result.put(KEY_RAW_LIST, resultList);"); + result = position >= resultList.size() ? new JSONObject() : resultList.get(position); + if (position == 0 && resultList.size() > 1 && result != null && result.isEmpty() == false) { + // 不是 main 不会直接执行,count=1 返回的不会超过 1 && config.isMain() && config.getCount() != 1 + Log.i(TAG, ">>> execute position == 0 && resultList.size() > 1 && result != null && result.isEmpty() == false" + + " >> result = new JSONObject(result); result.put(KEY_RAW_LIST, resultList);"); - result = new JSONObject(result); - result.put(KEY_RAW_LIST, resultList); + result = new JSONObject(result); + result.put(KEY_RAW_LIST, resultList); + } } long endTime = System.currentTimeMillis(); @@ -396,7 +401,7 @@ protected void executeAppJoin(SQLConfig config, List resultList, Map } continue; } - + jc = j.getJoinConfig(); //取出 "id@": "@/User/userId" 中所有 userId 的值 @@ -550,7 +555,7 @@ protected JSONObject onPutColumn(@NotNull SQLConfig config, @NotNull ResultSet r } } } - + } Object value = getValue(config, rs, rsmd, tablePosition, table, columnIndex, lable, childMap); @@ -561,7 +566,7 @@ protected JSONObject onPutColumn(@NotNull SQLConfig config, @NotNull ResultSet r } finalTable.put(lable, value); } - + return table; } @@ -581,7 +586,7 @@ protected List onPutTable(@NotNull SQLConfig config, @NotNull Result return resultList; } - + protected String getKey(@NotNull SQLConfig config, @NotNull ResultSet rs, @NotNull ResultSetMetaData rsmd , final int tablePosition, @NotNull JSONObject table, final int columnIndex, Map childMap) throws Exception {