You can not select more than 25 topics Topics must start with a letter or number, can include dashes ('-') and can be up to 35 characters long.

filter.go 1.7KB

12345678910111213141516171819202122232425262728293031323334353637383940414243444546474849505152535455565758596061626364656667686970717273747576
  1. // Copyright 2019 The Xorm Authors. All rights reserved.
  2. // Use of this source code is governed by a BSD-style
  3. // license that can be found in the LICENSE file.
  4. package dialects
  5. import (
  6. "fmt"
  7. "strings"
  8. )
  9. // Filter is an interface to filter SQL
  10. type Filter interface {
  11. Do(sql string) string
  12. }
  13. // SeqFilter filter SQL replace ?, ? ... to $1, $2 ...
  14. type SeqFilter struct {
  15. Prefix string
  16. Start int
  17. }
  18. func convertQuestionMark(sql, prefix string, start int) string {
  19. var buf strings.Builder
  20. var beginSingleQuote bool
  21. var isLineComment bool
  22. var isComment bool
  23. var isMaybeLineComment bool
  24. var isMaybeComment bool
  25. var isMaybeCommentEnd bool
  26. var index = start
  27. for _, c := range sql {
  28. if !beginSingleQuote && !isLineComment && !isComment && c == '?' {
  29. buf.WriteString(fmt.Sprintf("%s%v", prefix, index))
  30. index++
  31. } else {
  32. if isMaybeLineComment {
  33. if c == '-' {
  34. isLineComment = true
  35. }
  36. isMaybeLineComment = false
  37. } else if isMaybeComment {
  38. if c == '*' {
  39. isComment = true
  40. }
  41. isMaybeComment = false
  42. } else if isMaybeCommentEnd {
  43. if c == '/' {
  44. isComment = false
  45. }
  46. isMaybeCommentEnd = false
  47. } else if isLineComment {
  48. if c == '\n' {
  49. isLineComment = false
  50. }
  51. } else if isComment {
  52. if c == '*' {
  53. isMaybeCommentEnd = true
  54. }
  55. } else if !beginSingleQuote && c == '-' {
  56. isMaybeLineComment = true
  57. } else if !beginSingleQuote && c == '/' {
  58. isMaybeComment = true
  59. } else if c == '\'' {
  60. beginSingleQuote = !beginSingleQuote
  61. }
  62. buf.WriteRune(c)
  63. }
  64. }
  65. return buf.String()
  66. }
  67. // Do implements Filter
  68. func (s *SeqFilter) Do(sql string) string {
  69. return convertQuestionMark(sql, s.Prefix, s.Start)
  70. }