github.com/zlyuancn/zstr@v0.0.0-20230412074414-14d6b645962f/repair_sql.go (about) 1 /* 2 ------------------------------------------------- 3 Author : Zhang Fan 4 date: 2020/7/18 5 Description : 6 ------------------------------------------------- 7 */ 8 9 package zstr 10 11 import ( 12 "bytes" 13 ) 14 15 var emptyStrMap = map[int32]struct{}{ 16 '\f': {}, 17 '\n': {}, 18 '\r': {}, 19 '\t': {}, 20 '\v': {}, 21 ' ': {}, 22 0x85: {}, 23 0xA0: {}, 24 } 25 26 // 缩进空格 27 func (m *sqlTemplate) retractAllSpace(s string) string { 28 var buff bytes.Buffer 29 old := -2 30 var ok bool 31 for i, v := range []rune(s) { 32 if _, ok = emptyStrMap[v]; ok { 33 if i-old > 1 { 34 buff.WriteByte(' ') 35 } 36 old = i 37 } else { 38 buff.WriteRune(v) 39 } 40 } 41 42 return buff.String() 43 } 44 45 var repairSqlTexts = []struct { 46 Old string // 原始数据 47 New string // 新数据 48 Retract bool // 是否缩进 49 }{ 50 {"( and", "(", false}, 51 {"(and", "(", false}, 52 {"( or", "(", false}, 53 {"(or", "(", false}, 54 {"and ( )", "", true}, 55 {"and ()", "", true}, 56 {"or ( )", "", true}, 57 {"or ()", "", true}, 58 {"where ( )", "where", false}, 59 {"where ()", "where", false}, 60 {"where and ", "where ", false}, 61 {"where or ", "where ", false}, 62 {"where order by ", "order by ", false}, 63 {"where group by ", "group by ", false}, 64 {"where limit ", "limit ", false}, 65 {"where )", ")", false}, 66 } 67 var repairSqlSuffixes = []string{ 68 "where", 69 "where ", 70 "where;", 71 "where ;", 72 } 73 74 // 修复模板渲染后无效的sql语句 75 func (m *sqlTemplate) repairSql(sql string) string { 76 result := m.retractAllSpace(sql) 77 78 for _, r := range repairSqlTexts { 79 result = m.ReplaceAllIgnoreCase(result, r.Old, r.New) 80 if r.Retract { 81 result = m.retractAllSpace(result) 82 } 83 } 84 for _, suffix := range repairSqlSuffixes { 85 if m.HasSuffixIgnoreCase(result, suffix) { 86 result = result[:len(result)-len(suffix)] 87 return result 88 } 89 } 90 return result 91 } 92 93 // 忽略大小写检查字符相等 94 func (m *sqlTemplate) EqualCharIgnoreCase(c1, c2 int32) bool { 95 if c1 == c2 { 96 return true 97 } 98 switch c1 - c2 { 99 case 32: // a - A 100 return c1 >= 'a' && c1 <= 'z' 101 case -32: // A - a 102 return c1 >= 'A' && c1 <= 'Z' 103 } 104 return false 105 } 106 107 // 忽略大小写检查文本相等 108 func (m *sqlTemplate) EqualIgnoreCase(s1, s2 string) bool { 109 if s1 == s2 { 110 return true 111 } 112 113 r1 := []rune(s1) 114 r2 := []rune(s2) 115 if len(r1) != len(r2) { 116 return false 117 } 118 119 for i, r := range r1 { 120 if !m.EqualCharIgnoreCase(r, r2[i]) { 121 return false 122 } 123 } 124 return true 125 } 126 127 // 忽略大小写替换所有文本 128 func (m *sqlTemplate) ReplaceAllIgnoreCase(s, old, new string) string { 129 return m.ReplaceIgnoreCase(s, old, new, -1) 130 } 131 132 // 替换n次忽略大小写匹配的文本 133 func (m *sqlTemplate) ReplaceIgnoreCase(s, old, new string, n int) string { 134 if n == 0 || old == new || old == "" { 135 return s 136 } 137 138 ss := []rune(s) 139 sub := []rune(old) 140 var buff bytes.Buffer 141 var num int 142 for offset := 0; offset < len(ss); { 143 start := m.searchIgnoreCase(ss, sub, offset) 144 if start > -1 { 145 buff.WriteString(string(ss[offset:start])) 146 buff.WriteString(new) 147 offset = start + len(sub) 148 num++ 149 } 150 151 if start == -1 || num == n { 152 buff.WriteString(string(ss[offset:])) 153 break 154 } 155 } 156 return buff.String() 157 } 158 159 // 忽略大小写查找第一个匹配sub的文本所在位置, 如果不存在返回-1 160 func (m *sqlTemplate) searchIgnoreCase(ss []rune, sub []rune, start int) int { 161 if len(ss)-start < len(sub) { 162 return -1 163 } 164 165 var has bool 166 // 查找开头 167 for i := start; i < len(ss); i++ { 168 if m.EqualCharIgnoreCase(ss[i], sub[0]) { 169 start, has = i, true 170 break 171 } 172 } 173 if !has || len(ss)-start < len(sub) { 174 return -1 175 } 176 for i := 1; i < len(sub); i++ { 177 if !m.EqualCharIgnoreCase(ss[start+i], sub[i]) { 178 return m.searchIgnoreCase(ss, sub, start+1) 179 } 180 } 181 return start 182 } 183 184 // 忽略大小写查找第一个匹配sub的文本所在位置, 如果不存在返回-1 185 func (m *sqlTemplate) IndexIgnoreCase(s, sub string) int { 186 return m.searchIgnoreCase([]rune(s), []rune(sub), 0) 187 } 188 189 // 忽略大小写查找s是否包含sub 190 func (m *sqlTemplate) ContainsIgnoreCase(s, sub string) bool { 191 return m.IndexIgnoreCase(s, sub) >= 0 192 } 193 194 // 忽略大小写测试文本s是否以suffix结束 195 func (m *sqlTemplate) HasSuffixIgnoreCase(s, suffix string) bool { 196 return len(s) >= len(suffix) && m.EqualIgnoreCase(s[len(s)-len(suffix):], suffix) 197 }