@@ -60,6 +60,8 @@ public AbstractObjectParser setParser(AbstractParser<?> parser) {
6060 protected final int type ;
6161 protected final List <Join > joinList ;
6262 protected final boolean isTable ;
63+ protected final boolean isArrayMainTable ;
64+ protected final boolean isReuse ;
6365 protected final String path ;
6466 protected final String name ;
6567 protected final String table ;
@@ -96,6 +98,8 @@ public AbstractObjectParser(@NotNull JSONObject request, String parentPath, Stri
9698 this .table = entry .getKey ();
9799 this .alias = entry .getValue ();
98100 this .isTable = apijson .JSONObject .isTableKey (table );
101+ this .isArrayMainTable = isSubquery == false && this .isTable && this .type == SQLConfig .TYPE_ITEM_CHILD_0 && RequestMethod .isGetMethod (method , true );
102+ this .isReuse = isArrayMainTable && arrayConfig != null && arrayConfig .getPosition () > 0 ;
99103
100104 this .objectCount = 0 ;
101105 this .arrayCount = 0 ;
@@ -118,6 +122,15 @@ public AbstractObjectParser(@NotNull JSONObject request, String parentPath, Stri
118122 Log .d (TAG , "AbstractObjectParser isEmpty = " + isEmpty + "; tri = " + tri + "; drop = " + drop );
119123 }
120124
125+ protected int position ;
126+ public int getPosition () {
127+ return position ;
128+ }
129+ public AbstractObjectParser setPosition (int position ) {
130+ this .position = position ;
131+ return this ;
132+ }
133+
121134
122135 private boolean invalidate = false ;
123136 public void invalidate () {
@@ -260,7 +273,7 @@ else if (method == PUT && value instanceof JSONArray
260273 // 非Table内的函数会被滞后在onChildParse后调用! onFunctionResponse("-");
261274 }
262275
263- if (isTable ) {
276+ if (isReuse == false && isTable ) {
264277 if (parser .getGlobleDatabase () != null && sqlRequest .get (JSONRequest .KEY_DATABASE ) == null ) {
265278 sqlRequest .put (JSONRequest .KEY_DATABASE , parser .getGlobleDatabase ());
266279 }
@@ -297,96 +310,96 @@ else if (method == PUT && value instanceof JSONArray
297310 */
298311 @ Override
299312 public boolean onParse (@ NotNull String key , @ NotNull Object value ) throws Exception {
300- if (key .endsWith ("@" )) {//StringUtil.isPath((String) value)) {
301-
302- if (value instanceof JSONObject ) { // SQL 子查询对象,JSONObject -> SQLConfig.getSQL
303- String replaceKey = key .substring (0 , key .length () - 1 );//key{}@ getRealKey
304-
305- JSONObject subquery = (JSONObject ) value ;
306- String range = subquery .getString (JSONRequest .KEY_SUBQUERY_RANGE );
307- if (range != null && JSONRequest .SUBQUERY_RANGE_ALL .equals (range ) == false && JSONRequest .SUBQUERY_RANGE_ANY .equals (range ) == false ) {
308- throw new IllegalArgumentException ("子查询 " + path + "/" + key + ":{ range:value } 中 value 只能为 [" + JSONRequest .SUBQUERY_RANGE_ALL + ", " + JSONRequest .SUBQUERY_RANGE_ANY + "] 中的一个!" );
309- }
310-
313+ if (key .endsWith ("@" )) { // StringUtil.isPath((String) value)) {
314+ String replaceKey = key .substring (0 , key .length () - 1 );
315+
316+ // [] 内主表 position > 0 时,用来生成 SQLConfig 的键值对全都忽略,不解析
317+ // if (isReuse == false || replaceKey.endsWith("()") || (replaceKey.startsWith("@") && JSONRequest.TABLE_KEY_LIST.contains(replaceKey) == false)) {
318+ if (value instanceof JSONObject ) { // key{}@ getRealKey, SQL 子查询对象,JSONObject -> SQLConfig.getSQL
319+
320+ JSONObject subquery = (JSONObject ) value ;
321+ String range = subquery .getString (JSONRequest .KEY_SUBQUERY_RANGE );
322+ if (range != null && JSONRequest .SUBQUERY_RANGE_ALL .equals (range ) == false && JSONRequest .SUBQUERY_RANGE_ANY .equals (range ) == false ) {
323+ throw new IllegalArgumentException ("子查询 " + path + "/" + key + ":{ range:value } 中 value 只能为 [" + JSONRequest .SUBQUERY_RANGE_ALL + ", " + JSONRequest .SUBQUERY_RANGE_ANY + "] 中的一个!" );
324+ }
311325
312- JSONArray arr = parser .onArrayParse (subquery , path , key , true );
313326
314- JSONObject obj = arr == null || arr .isEmpty () ? null : arr .getJSONObject (0 );
315- if (obj == null ) {
316- throw new Exception ("服务器内部错误,解析子查询 " + path + "/" + key + ":{ } 为 Subquery 对象失败!" );
317- }
327+ JSONArray arr = parser .onArrayParse (subquery , path , key , true );
318328
319- String from = subquery .getString (JSONRequest .KEY_SUBQUERY_FROM );
320- JSONObject arrObj = from == null ? null : obj .getJSONObject (from );
321- if (arrObj == null ) {
322- throw new IllegalArgumentException ("子查询 " + path + "/" + key + ":{ from:value } 中 value 对应的主表对象 " + from + ":{} 不存在!" );
323- }
324- //
325- SQLConfig cfg = (SQLConfig ) arrObj .get (AbstractParser .KEY_CONFIG );
326- if (cfg == null ) {
327- throw new NotExistException (TAG + ".onParse cfg == null" );
328- }
329-
330- Subquery s = new Subquery ();
331- s .setPath (path );
332- s .setOriginKey (key );
333- s .setOriginValue (subquery );
334-
335- s .setFrom (from );
336- s .setRange (range );
337- s .setKey (replaceKey );
338- s .setConfig (cfg );
329+ JSONObject obj = arr == null || arr .isEmpty () ? null : arr .getJSONObject (0 );
330+ if (obj == null ) {
331+ throw new Exception ("服务器内部错误,解析子查询 " + path + "/" + key + ":{ } 为 Subquery 对象失败!" );
332+ }
339333
340- key = replaceKey ;
341- value = s ; //(range == null || range.isEmpty() ? "" : "range") + "(" + cfg.getSQL(false) + ") ";
334+ String from = subquery .getString (JSONRequest .KEY_SUBQUERY_FROM );
335+ JSONObject arrObj = from == null ? null : obj .getJSONObject (from );
336+ if (arrObj == null ) {
337+ throw new IllegalArgumentException ("子查询 " + path + "/" + key + ":{ from:value } 中 value 对应的主表对象 " + from + ":{} 不存在!" );
338+ }
339+ //
340+ SQLConfig cfg = (SQLConfig ) arrObj .get (AbstractParser .KEY_CONFIG );
341+ if (cfg == null ) {
342+ throw new NotExistException (TAG + ".onParse cfg == null" );
343+ }
342344
343- parser .putQueryResult (AbstractParser .getAbsPath (path , key ), s ); //字符串引用保证不了安全性 parser.getSQL(cfg));
344- }
345- else if (value instanceof String ) { // 引用赋值路径
345+ Subquery s = new Subquery ();
346+ s .setPath (path );
347+ s .setOriginKey (key );
348+ s .setOriginValue (subquery );
346349
347- // System.out.println("getObject key.endsWith(@) >> parseRelation = " + parseRelation );
348- String replaceKey = key . substring ( 0 , key . length () - 1 ); //key{}@ getRealKey
349- String targetPath = AbstractParser . getValuePath ( type == TYPE_ITEM
350- ? path : parentPath , new String (( String ) value ) );
350+ s . setFrom ( from );
351+ s . setRange ( range );
352+ s . setKey ( replaceKey );
353+ s . setConfig ( cfg );
351354
352- //先尝试获取,尽量保留缺省依赖路径,这样就不需要担心路径改变
353- Object target = onReferenceParse (targetPath );
354- Log .i (TAG , "onParse targetPath = " + targetPath + "; target = " + target );
355+ key = replaceKey ;
356+ value = s ; //(range == null || range.isEmpty() ? "" : "range") + "(" + cfg.getSQL(false) + ") ";
355357
356- if (target == null ) {//String#equals(null)会出错
357- Log .d (TAG , "onParse target == null >> return true;" );
358- return true ;
358+ parser .putQueryResult (AbstractParser .getAbsPath (path , key ), s ); //字符串引用保证不了安全性 parser.getSQL(cfg));
359359 }
360- if (target instanceof Map ) { //target可能是从requestObject里取出的 {}
361- if (isTable || targetPath .endsWith ("[]/" + JSONResponse .KEY_INFO ) == false ) {
362- Log .d (TAG , "onParse target instanceof Map >> return false;" );
363- return false ; //FIXME 这个判断现在来看是否还有必要?为啥不允许为 JSONObject ?以前可能因为防止二次遍历再解析,现在只有一次遍历
360+ else if (value instanceof String ) { // //key{}@ getRealKey, 引用赋值路径
361+ // System.out.println("getObject key.endsWith(@) >> parseRelation = " + parseRelation);
362+ String targetPath = AbstractParser .getValuePath (type == TYPE_ITEM
363+ ? path : parentPath , new String ((String ) value ));
364+
365+ //先尝试获取,尽量保留缺省依赖路径,这样就不需要担心路径改变
366+ Object target = onReferenceParse (targetPath );
367+ Log .i (TAG , "onParse targetPath = " + targetPath + "; target = " + target );
368+
369+ if (target == null ) {//String#equals(null)会出错
370+ Log .d (TAG , "onParse target == null >> return true;" );
371+ return true ;
364372 }
365- }
366- if (targetPath .equals (target )) {//必须valuePath和保证getValueByPath传进去的一致!
367- Log .d (TAG , "onParse targetPath.equals(target) >>" );
368-
369- //非查询关键词 @key 不影响查询,直接跳过
370- if (isTable && (key .startsWith ("@" ) == false || JSONRequest .TABLE_KEY_LIST .contains (key ))) {
371- Log .e (TAG , "onParse isTable && (key.startsWith(@) == false"
372- + " || JSONRequest.TABLE_KEY_LIST.contains(key)) >> return null;" );
373- return false ;//获取不到就不用再做无效的query了。不考虑 Table:{Table:{}}嵌套
374- } else {
375- Log .d (TAG , "onParse isTable(table) == false >> return true;" );
376- return true ;//舍去,对Table无影响
373+ if (target instanceof Map ) { //target可能是从requestObject里取出的 {}
374+ if (isTable || targetPath .endsWith ("[]/" + JSONResponse .KEY_INFO ) == false ) {
375+ Log .d (TAG , "onParse target instanceof Map >> return false;" );
376+ return false ; //FIXME 这个判断现在来看是否还有必要?为啥不允许为 JSONObject ?以前可能因为防止二次遍历再解析,现在只有一次遍历
377+ }
377378 }
378- }
379-
380- //直接替换原来的key@:path为key:target
381- Log .i (TAG , "onParse >> key = replaceKey; value = target;" );
382- key = replaceKey ;
383- value = target ;
384- Log .d (TAG , "onParse key = " + key + "; value = " + value );
385- }
386- else {
387- throw new IllegalArgumentException (path + "/" + key + ":value 中 value 必须为 依赖路径String 或 SQL子查询JSONObject !" );
388- }
379+ if (targetPath .equals (target )) {//必须valuePath和保证getValueByPath传进去的一致!
380+ Log .d (TAG , "onParse targetPath.equals(target) >>" );
381+
382+ //非查询关键词 @key 不影响查询,直接跳过
383+ if (isTable && (key .startsWith ("@" ) == false || JSONRequest .TABLE_KEY_LIST .contains (key ))) {
384+ Log .e (TAG , "onParse isTable && (key.startsWith(@) == false"
385+ + " || JSONRequest.TABLE_KEY_LIST.contains(key)) >> return null;" );
386+ return false ;//获取不到就不用再做无效的query了。不考虑 Table:{Table:{}}嵌套
387+ } else {
388+ Log .d (TAG , "onParse isTable(table) == false >> return true;" );
389+ return true ;//舍去,对Table无影响
390+ }
391+ }
389392
393+ //直接替换原来的key@:path为key:target
394+ Log .i (TAG , "onParse >> key = replaceKey; value = target;" );
395+ key = replaceKey ;
396+ value = target ;
397+ Log .d (TAG , "onParse key = " + key + "; value = " + value );
398+ }
399+ else {
400+ throw new IllegalArgumentException (path + "/" + key + ":value 中 value 必须为 依赖路径String 或 SQL子查询JSONObject !" );
401+ }
402+ // }
390403 }
391404
392405 if (key .endsWith ("()" )) {
@@ -426,7 +439,9 @@ else if (isTable && key.startsWith("@") && JSONRequest.TABLE_KEY_LIST.contains(k
426439 customMap .put (key , value );
427440 }
428441 else {
442+ // 导致副表从 1 开始都不查了 if (isReuse == false) {
429443 sqlRequest .put (key , value );
444+ // }
430445 }
431446
432447 return true ;
@@ -640,8 +655,8 @@ public AbstractObjectParser setSQLConfig() throws Exception {
640655
641656 @ Override
642657 public AbstractObjectParser setSQLConfig (int count , int page , int position ) throws Exception {
643- if (isTable == false ) {
644- return this ;
658+ if (isTable == false || isReuse ) {
659+ return setPosition ( position ) ;
645660 }
646661
647662 if (sqlConfig == null ) {
@@ -676,28 +691,30 @@ public AbstractObjectParser executeSQL() throws Exception {
676691 //执行SQL操作数据库
677692 if (isTable == false ) {//提高性能
678693 sqlReponse = new JSONObject (sqlRequest );
679- } else {
680- try {
681- sqlReponse = onSQLExecute ();
682- }
683- catch (NotExistException e ) {
684- // Log.e(TAG, "getObject try { response = getSQLObject(config2); } catch (Exception e) {");
685- // if (e instanceof NotExistException) {//非严重异常,有时候只是数据不存在
686- // // e.printStackTrace();
687- sqlReponse = null ;//内部吃掉异常,put到最外层
688- // requestObject.put(JSONResponse.KEY_MSG
689- // , StringUtil.getString(requestObject.get(JSONResponse.KEY_MSG)
690- // + "; query " + path + " cath NotExistException:"
691- // + newErrorResult(e).getString(JSONResponse.KEY_MSG)));
692- // } else {
693- // throw e;
694- // }
694+ }
695+ else {
696+ try {
697+ sqlReponse = onSQLExecute ();
698+
699+ }
700+ catch (NotExistException e ) {
701+ // Log.e(TAG, "getObject try { response = getSQLObject(config2); } catch (Exception e) {");
702+ // if (e instanceof NotExistException) {//非严重异常,有时候只是数据不存在
703+ // // e.printStackTrace();
704+ sqlReponse = null ;//内部吃掉异常,put到最外层
705+ // requestObject.put(JSONResponse.KEY_MSG
706+ // , StringUtil.getString(requestObject.get(JSONResponse.KEY_MSG)
707+ // + "; query " + path + " cath NotExistException:"
708+ // + newErrorResult(e).getString(JSONResponse.KEY_MSG)));
709+ // } else {
710+ // throw e;
711+ // }
712+ }
695713 }
696714
697715 if (drop ) {//丢弃Table,只为了向下提供条件
698716 sqlReponse = null ;
699717 }
700- }
701718
702719 return this ;
703720 }
@@ -799,10 +816,39 @@ public Object onReferenceParse(@NotNull String path) {
799816
800817 @ Override
801818 public JSONObject onSQLExecute () throws Exception {
802- JSONObject result = parser .executeSQL (sqlConfig , isSubquery );
803- if (isSubquery == false && result != null ) {
804- parser .putQueryResult (path , result );//解决获取关联数据时requestObject里不存在需要的关联数据
819+ int position = getPosition ();
820+
821+ JSONObject result ;
822+ if (isArrayMainTable && position > 0 ) { // 数组主表使用专门的缓存数据
823+ result = parser .getArrayMainCacheItem (parentPath .substring (0 , parentPath .lastIndexOf ("[]" ) + 2 ), position );
805824 }
825+ else {
826+ result = parser .executeSQL (sqlConfig , isSubquery );
827+
828+ if (isArrayMainTable && position == 0 && result != null ) { // 提取并缓存数组主表的列表数据
829+ @ SuppressWarnings ("unchecked" )
830+ List <JSONObject > list = (List <JSONObject >) result .remove (SQLExecutor .KEY_RAW_LIST );
831+ if (list != null ) {
832+ String arrayPath = parentPath .substring (0 , parentPath .lastIndexOf ("[]" ) + 2 );
833+
834+ for (int i = 1 ; i < list .size (); i ++) { // 从 1 开始,0 已经处理过
835+ JSONObject obj = parser .parseCorrectResponse (table , list .get (i ));
836+ list .set (i , obj );
837+
838+ if (obj != null ) {
839+ parser .putQueryResult (arrayPath + "/" + i + "/" + table , obj ); //解决获取关联数据时requestObject里不存在需要的关联数据
840+ }
841+ }
842+
843+ parser .putArrayMainCache (arrayPath , list );
844+ }
845+ }
846+
847+ if (isSubquery == false && result != null ) {
848+ parser .putQueryResult (path , result );//解决获取关联数据时requestObject里不存在需要的关联数据
849+ }
850+ }
851+
806852 return result ;
807853 }
808854
0 commit comments