本站源代码
您最多选择25个主题 主题必须以字母或数字开头,可以包含连字符 (-),并且长度不得超过35个字符

266 行
4.1KB

  1. // Package querytext is the old query parser and parameter substitute process.
  2. // Do not use on new code.
  3. //
  4. // This package is not subject to any API compatibility guarantee.
  5. package querytext
  6. import (
  7. "bytes"
  8. "io"
  9. "strconv"
  10. )
  11. type parser struct {
  12. r *bytes.Reader
  13. w bytes.Buffer
  14. paramCount int
  15. paramMax int
  16. // using map as a set
  17. namedParams map[string]bool
  18. }
  19. func (p *parser) next() (rune, bool) {
  20. ch, _, err := p.r.ReadRune()
  21. if err != nil {
  22. if err != io.EOF {
  23. panic(err)
  24. }
  25. return 0, false
  26. }
  27. return ch, true
  28. }
  29. func (p *parser) unread() {
  30. err := p.r.UnreadRune()
  31. if err != nil {
  32. panic(err)
  33. }
  34. }
  35. func (p *parser) write(ch rune) {
  36. p.w.WriteRune(ch)
  37. }
  38. type stateFunc func(*parser) stateFunc
  39. // ParseParams rewrites the query from using "?" placeholders
  40. // to using "@pN" parameter names that SQL Server will accept.
  41. //
  42. // This function and package is not subject to any API compatibility guarantee.
  43. func ParseParams(query string) (string, int) {
  44. p := &parser{
  45. r: bytes.NewReader([]byte(query)),
  46. namedParams: map[string]bool{},
  47. }
  48. state := parseNormal
  49. for state != nil {
  50. state = state(p)
  51. }
  52. return p.w.String(), p.paramMax + len(p.namedParams)
  53. }
  54. func parseNormal(p *parser) stateFunc {
  55. for {
  56. ch, ok := p.next()
  57. if !ok {
  58. return nil
  59. }
  60. if ch == '?' {
  61. return parseOrdinalParameter
  62. } else if ch == '$' || ch == ':' {
  63. ch2, ok := p.next()
  64. if !ok {
  65. p.write(ch)
  66. return nil
  67. }
  68. p.unread()
  69. if ch2 >= '0' && ch2 <= '9' {
  70. return parseOrdinalParameter
  71. } else if 'a' <= ch2 && ch2 <= 'z' || 'A' <= ch2 && ch2 <= 'Z' {
  72. return parseNamedParameter
  73. }
  74. }
  75. p.write(ch)
  76. switch ch {
  77. case '\'':
  78. return parseQuote
  79. case '"':
  80. return parseDoubleQuote
  81. case '[':
  82. return parseBracket
  83. case '-':
  84. return parseLineComment
  85. case '/':
  86. return parseComment
  87. }
  88. }
  89. }
  90. func parseOrdinalParameter(p *parser) stateFunc {
  91. var paramN int
  92. var ok bool
  93. for {
  94. var ch rune
  95. ch, ok = p.next()
  96. if ok && ch >= '0' && ch <= '9' {
  97. paramN = paramN*10 + int(ch-'0')
  98. } else {
  99. break
  100. }
  101. }
  102. if ok {
  103. p.unread()
  104. }
  105. if paramN == 0 {
  106. p.paramCount++
  107. paramN = p.paramCount
  108. }
  109. if paramN > p.paramMax {
  110. p.paramMax = paramN
  111. }
  112. p.w.WriteString("@p")
  113. p.w.WriteString(strconv.Itoa(paramN))
  114. if !ok {
  115. return nil
  116. }
  117. return parseNormal
  118. }
  119. func parseNamedParameter(p *parser) stateFunc {
  120. var paramName string
  121. var ok bool
  122. for {
  123. var ch rune
  124. ch, ok = p.next()
  125. if ok && (ch >= '0' && ch <= '9' || 'a' <= ch && ch <= 'z' || 'A' <= ch && ch <= 'Z') {
  126. paramName = paramName + string(ch)
  127. } else {
  128. break
  129. }
  130. }
  131. if ok {
  132. p.unread()
  133. }
  134. p.namedParams[paramName] = true
  135. p.w.WriteString("@")
  136. p.w.WriteString(paramName)
  137. if !ok {
  138. return nil
  139. }
  140. return parseNormal
  141. }
  142. func parseQuote(p *parser) stateFunc {
  143. for {
  144. ch, ok := p.next()
  145. if !ok {
  146. return nil
  147. }
  148. p.write(ch)
  149. if ch == '\'' {
  150. return parseNormal
  151. }
  152. }
  153. }
  154. func parseDoubleQuote(p *parser) stateFunc {
  155. for {
  156. ch, ok := p.next()
  157. if !ok {
  158. return nil
  159. }
  160. p.write(ch)
  161. if ch == '"' {
  162. return parseNormal
  163. }
  164. }
  165. }
  166. func parseBracket(p *parser) stateFunc {
  167. for {
  168. ch, ok := p.next()
  169. if !ok {
  170. return nil
  171. }
  172. p.write(ch)
  173. if ch == ']' {
  174. ch, ok = p.next()
  175. if !ok {
  176. return nil
  177. }
  178. if ch != ']' {
  179. p.unread()
  180. return parseNormal
  181. }
  182. p.write(ch)
  183. }
  184. }
  185. }
  186. func parseLineComment(p *parser) stateFunc {
  187. ch, ok := p.next()
  188. if !ok {
  189. return nil
  190. }
  191. if ch != '-' {
  192. p.unread()
  193. return parseNormal
  194. }
  195. p.write(ch)
  196. for {
  197. ch, ok = p.next()
  198. if !ok {
  199. return nil
  200. }
  201. p.write(ch)
  202. if ch == '\n' {
  203. return parseNormal
  204. }
  205. }
  206. }
  207. func parseComment(p *parser) stateFunc {
  208. var nested int
  209. ch, ok := p.next()
  210. if !ok {
  211. return nil
  212. }
  213. if ch != '*' {
  214. p.unread()
  215. return parseNormal
  216. }
  217. p.write(ch)
  218. for {
  219. ch, ok = p.next()
  220. if !ok {
  221. return nil
  222. }
  223. p.write(ch)
  224. for ch == '*' {
  225. ch, ok = p.next()
  226. if !ok {
  227. return nil
  228. }
  229. p.write(ch)
  230. if ch == '/' {
  231. if nested == 0 {
  232. return parseNormal
  233. } else {
  234. nested--
  235. }
  236. }
  237. }
  238. for ch == '/' {
  239. ch, ok = p.next()
  240. if !ok {
  241. return nil
  242. }
  243. p.write(ch)
  244. if ch == '*' {
  245. nested++
  246. }
  247. }
  248. }
  249. }
上海开阖软件有限公司 沪ICP备12045867号-1