Commit de93953303db3a8cadcde8f09289a81e6576d7b8

Authored by 王彬
1 parent 07ecddbb

fix a bug about core sql split

src/main/java/com/taover/repository/UtilsSql.java
@@ -2,6 +2,7 @@ package com.taover.repository; @@ -2,6 +2,7 @@ package com.taover.repository;
2 2
3 import java.util.HashMap; 3 import java.util.HashMap;
4 import java.util.Map; 4 import java.util.Map;
  5 +import java.util.Stack;
5 6
6 import org.springframework.util.StringUtils; 7 import org.springframework.util.StringUtils;
7 8
@@ -9,62 +10,80 @@ public class UtilsSql { @@ -9,62 +10,80 @@ public class UtilsSql {
9 10
10 public static String[] splitCoreSql(String coreSql) throws Exception { 11 public static String[] splitCoreSql(String coreSql) throws Exception {
11 //去除''内的信息 12 //去除''内的信息
12 - String coreSqlRemoveQuate = replaceSelectAndFromBetweenTopCornerMark(coreSql.toUpperCase());  
13 - int fromIndex = calcFromIndex(coreSqlRemoveQuate); 13 + int fromIndex = calcFromIndex(coreSql);
14 if(fromIndex > -1) { 14 if(fromIndex > -1) {
15 return new String[] {coreSql.substring(0, fromIndex), coreSql.substring(fromIndex, coreSql.length())}; 15 return new String[] {coreSql.substring(0, fromIndex), coreSql.substring(fromIndex, coreSql.length())};
16 }else { 16 }else {
17 throw new Exception("未找到FROM子句"); 17 throw new Exception("未找到FROM子句");
18 } 18 }
19 } 19 }
20 -  
21 - private static int calcFromIndex(String coreSqlUpper) {  
22 - //计算位置  
23 - int selectSubSqlNum = 0;  
24 - int currWindowIndex = 0;  
25 - for(currWindowIndex=0; (currWindowIndex+6)<coreSqlUpper.length(); ) {  
26 - String currSubStr = coreSqlUpper.substring(currWindowIndex, currWindowIndex+6);  
27 - if("SELECT".equals(currSubStr)) {  
28 - ++selectSubSqlNum;  
29 - currWindowIndex += 6;  
30 - }else if(currSubStr.startsWith(" FROM")) {  
31 - if(selectSubSqlNum == 1) {  
32 - return currWindowIndex;  
33 - }  
34 - --selectSubSqlNum;  
35 - currWindowIndex += 5; 20 +
  21 + private static int calcFromIndex(String coreSql) {
  22 + Stack<String> operStack = new Stack<String>();
  23 + String coreSqlUpperCase = coreSql.toUpperCase();
  24 + int sqlLen = coreSqlUpperCase.length();
  25 + int currIndex = 0;
  26 + while(currIndex < sqlLen) {
  27 + String originContainBlank = subFirstStrEndWithBlank(coreSqlUpperCase, currIndex);
  28 + String itemWithoutBlank = originContainBlank.trim();
  29 + if("".equals(itemWithoutBlank)) {
  30 + currIndex += originContainBlank.length();
  31 + continue;
36 } 32 }
37 - ++currWindowIndex; 33 + if(operStack.isEmpty() && "FROM".equals(itemWithoutBlank)) {
  34 + return currIndex;
  35 + }
  36 + dealCoupleMark(itemWithoutBlank, operStack);
  37 + currIndex += originContainBlank.length();
38 } 38 }
39 return -1; 39 return -1;
40 } 40 }
41 -  
42 - private static String replaceSelectAndFromBetweenTopCornerMark(String sql) {  
43 - StringBuffer result = new StringBuffer();  
44 - boolean isBetweenMark = false;  
45 - int iMark = 0;  
46 - int currIndex = 0;  
47 - for(currIndex=0; currIndex<sql.length(); ++currIndex) {  
48 - char currChar = sql.charAt(currIndex);  
49 - if(currChar == '\'') {  
50 - if(!isBetweenMark) {  
51 - result.append(sql.substring(iMark, currIndex));  
52 - isBetweenMark = true;  
53 - }else {  
54 - result.append(sql.substring(iMark, currIndex).replaceAll("SELECT", "******").replaceAll("FROM", "****"));  
55 - isBetweenMark = false; 41 + private static void dealCoupleMark(String itemWithoutBlank, Stack<String> operStack) {
  42 + char preChar = ' ';
  43 + for(int i=0; i<itemWithoutBlank.length(); ++i) {
  44 + char currChar = itemWithoutBlank.charAt(i);
  45 + if(preChar != '\\' && currChar == '\'') {
  46 + if(operStack.isEmpty() || !operStack.peek().equals("'")) {
  47 + operStack.push("'");
  48 + }else if(operStack.peek().equals("'")) {
  49 + operStack.pop();
  50 + }
  51 + }else if(currChar == '('){
  52 + if(operStack.isEmpty() || !operStack.peek().equals("'")) {
  53 + operStack.push("(");
  54 + }
  55 + }else if(currChar == ')') {
  56 + if(!operStack.isEmpty() && operStack.peek().equals("(")) {
  57 + operStack.pop();
56 } 58 }
57 - iMark = currIndex;  
58 - }else if(currChar == '\\') {  
59 - ++currIndex;  
60 } 59 }
  60 + preChar = currChar;
61 } 61 }
62 - if(iMark > -1) {  
63 - result.append(sql.substring(iMark, currIndex));  
64 - }  
65 - return result.toString();  
66 } 62 }
67 - 63 +
  64 + private static String subFirstStrEndWithBlank(String coreSqlUpperCase, int startIndex) {
  65 + boolean startWithBlank = coreSqlUpperCase.charAt(startIndex)==' ';
  66 + int endIndex = startIndex;
  67 + int sqlLen = coreSqlUpperCase.length();
  68 + char preChar = '0';
  69 + for(int i=startIndex; i<sqlLen; ++i) {
  70 + char currChar = coreSqlUpperCase.charAt(i);
  71 + if(startWithBlank && currChar!=' ') {
  72 + endIndex = i;
  73 + break;
  74 + }
  75 + if(!startWithBlank && currChar!=' ' && preChar==' ') {
  76 + endIndex = i;
  77 + break;
  78 + }
  79 + preChar = currChar;
  80 + if(i == sqlLen-1) {
  81 + endIndex = sqlLen;
  82 + }
  83 + }
  84 + return coreSqlUpperCase.substring(startIndex, endIndex);
  85 + }
  86 +
68 /** 87 /**
69 * 获取排序字符串 88 * 获取排序字符串
70 * @param sort 89 * @param sort
@@ -145,7 +164,8 @@ public class UtilsSql { @@ -145,7 +164,8 @@ public class UtilsSql {
145 164
146 public static void main(String[] args) { 165 public static void main(String[] args) {
147 String[] testSql = new String[] { 166 String[] testSql = new String[] {
148 - "select actionFrom t,(select * as 'fromCActio', dd as 'seelctsele\'ctd' from t) from www where 223", 167 + "\\",
  168 + "select actionFrom as 'seelctsele\\'ctd',(select a as 'fromCActio' from t) from www where 223=1 ",
149 "SELECT wxorder_order.refund_way refundWay,wxorder_order.refund_delivery_sn refundDeliverySn, (SELECT sum(wxorder_compensate.`ware_refund_money`) from `wxorder_compensate` where wxorder_compensate.`order_id` = wxorder_order.id) as wareRefundMoney,(SELECT sum(wxorder_compensate.`refund_money`) from `wxorder_compensate` where wxorder_compensate.`order_id` = wxorder_order.id) as refundMoney, wxorder_order.operate_refund_time applyCompensateTime,wxorder_order.refund_instructions refundInstructions, wxorder_order.channel_id channelId, wxorder_channel.name channelName, wxorder_channel.platform_code platformCode, wxorder_order.pre_control_status as refundPreStatus, wxorder_order.ware_id wareId, wxorder_ware.name wareName, wxorder_order.id, wxorder_order.order_sn orderSn, wxorder_order.upload_sn uploadSn, wxorder_order.money_paid moneyPaid, wxorder_order.consignee, wxorder_order.mobile, wxorder_order.province_name provinceName, wxorder_order.city_name cityName, wxorder_order.district_name districtName, wxorder_order.address, wxorder_order.channel_remark channelRemark, wxorder_order.customer_remark customerRemark, wxorder_order.platform_customer_remark platformCustomerRemark, wxorder_order.sender_name senderName, wxorder_order.sender_mobile senderMobile, date_format(wxorder_order.create_time, '%Y-%m-%d %H:%i:%s') createTime, date_format(wxorder_order.real_delivery_time, '%Y-%m-%d %H:%i:%s') realDeliveryTime, wxorder_order.progress_distribute progressDistribute, wxorder_order.progress_delivery progressDelivery, wxorder_order.control_status controlStatus, wxorder_order.express_name expressName, wxorder_order.express_number expressNumber,wxorder_order.shipping_price shippingPrice, wxorder_order.customer_network_name ,(select count(*) from wxorder_compensate WHERE wxorder_compensate.order_id = wxorder_order.id) as compensateCountAll,(select count(*) from wxorder_compensate WHERE wxorder_compensate.order_id = wxorder_order.id and wxorder_compensate.progress_status = 1) as compensateCountDealed ,(select count(*) from wxorder_channel_refund_payment where wxorder_channel_refund_payment.order_id = wxorder_order.id) as channelRefundPaymentStatus,(select count(*) from wxorder_ware_refund_payment where wxorder_ware_refund_payment.order_id = wxorder_order.id) as wareRefundPaymentStatus FROM wxorder_order wxorder_order INNER JOIN wxorder_channel wxorder_channel ON wxorder_order.channel_id=wxorder_channel.id and wxorder_channel.tenant_id=54 INNER JOIN wxorder_ware wxorder_ware ON wxorder_order.ware_id=wxorder_ware.id and wxorder_ware.tenant_id=54 INNER JOIN wxorder_order_goods wxorder_order_goods ON wxorder_order.id=wxorder_order_goods.order_id and wxorder_order_goods.tenant_id=54 WHERE 1=1 AND wxorder_order.tenant_id='54' AND wxorder_order.control_status='4' GROUP BY wxorder_order.id", 169 "SELECT wxorder_order.refund_way refundWay,wxorder_order.refund_delivery_sn refundDeliverySn, (SELECT sum(wxorder_compensate.`ware_refund_money`) from `wxorder_compensate` where wxorder_compensate.`order_id` = wxorder_order.id) as wareRefundMoney,(SELECT sum(wxorder_compensate.`refund_money`) from `wxorder_compensate` where wxorder_compensate.`order_id` = wxorder_order.id) as refundMoney, wxorder_order.operate_refund_time applyCompensateTime,wxorder_order.refund_instructions refundInstructions, wxorder_order.channel_id channelId, wxorder_channel.name channelName, wxorder_channel.platform_code platformCode, wxorder_order.pre_control_status as refundPreStatus, wxorder_order.ware_id wareId, wxorder_ware.name wareName, wxorder_order.id, wxorder_order.order_sn orderSn, wxorder_order.upload_sn uploadSn, wxorder_order.money_paid moneyPaid, wxorder_order.consignee, wxorder_order.mobile, wxorder_order.province_name provinceName, wxorder_order.city_name cityName, wxorder_order.district_name districtName, wxorder_order.address, wxorder_order.channel_remark channelRemark, wxorder_order.customer_remark customerRemark, wxorder_order.platform_customer_remark platformCustomerRemark, wxorder_order.sender_name senderName, wxorder_order.sender_mobile senderMobile, date_format(wxorder_order.create_time, '%Y-%m-%d %H:%i:%s') createTime, date_format(wxorder_order.real_delivery_time, '%Y-%m-%d %H:%i:%s') realDeliveryTime, wxorder_order.progress_distribute progressDistribute, wxorder_order.progress_delivery progressDelivery, wxorder_order.control_status controlStatus, wxorder_order.express_name expressName, wxorder_order.express_number expressNumber,wxorder_order.shipping_price shippingPrice, wxorder_order.customer_network_name ,(select count(*) from wxorder_compensate WHERE wxorder_compensate.order_id = wxorder_order.id) as compensateCountAll,(select count(*) from wxorder_compensate WHERE wxorder_compensate.order_id = wxorder_order.id and wxorder_compensate.progress_status = 1) as compensateCountDealed ,(select count(*) from wxorder_channel_refund_payment where wxorder_channel_refund_payment.order_id = wxorder_order.id) as channelRefundPaymentStatus,(select count(*) from wxorder_ware_refund_payment where wxorder_ware_refund_payment.order_id = wxorder_order.id) as wareRefundPaymentStatus FROM wxorder_order wxorder_order INNER JOIN wxorder_channel wxorder_channel ON wxorder_order.channel_id=wxorder_channel.id and wxorder_channel.tenant_id=54 INNER JOIN wxorder_ware wxorder_ware ON wxorder_order.ware_id=wxorder_ware.id and wxorder_ware.tenant_id=54 INNER JOIN wxorder_order_goods wxorder_order_goods ON wxorder_order.id=wxorder_order_goods.order_id and wxorder_order_goods.tenant_id=54 WHERE 1=1 AND wxorder_order.tenant_id='54' AND wxorder_order.control_status='4' GROUP BY wxorder_order.id",
150 "select wdd, fromType from www where 223", 170 "select wdd, fromType from www where 223",
151 }; 171 };
@@ -156,9 +176,14 @@ public class UtilsSql { @@ -156,9 +176,14 @@ public class UtilsSql {
156 String[] data = splitCoreSql(item); 176 String[] data = splitCoreSql(item);
157 System.out.println(data[0]); 177 System.out.println(data[0]);
158 System.out.println(data[1]); 178 System.out.println(data[1]);
159 - } 179 + }
160 } catch (Exception e) { 180 } catch (Exception e) {
161 e.printStackTrace(); 181 e.printStackTrace();
162 } 182 }
  183 +
  184 +// String testSub = " asdf asdf asdfaf";
  185 +// System.out.println(subFirstStrEndWithBlank(testSub, 5));
  186 +// System.out.println(subFirstStrEndWithBlank(testSub, 6));
  187 +// System.out.println(subFirstStrEndWithBlank(testSub, 13));
163 } 188 }
164 } 189 }