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.

294 lines
5.8 KiB

2 years ago
  1. package vql
  2. import (
  3. "encoding/json"
  4. "fmt"
  5. "strings"
  6. "github.com/tidwall/gjson"
  7. )
  8. type Builder2 struct {
  9. As string `json:"as"`
  10. Select interface{} `json:"select"`
  11. From interface{} `json:"from"`
  12. Join interface{} `json:"join"`
  13. Where interface{} `json:"where"`
  14. Group interface{} `json:"group"`
  15. Having interface{} `json:"having"`
  16. Order interface{} `json:"order"`
  17. }
  18. func NewBuilder2() *Builder2 {
  19. return &Builder2{}
  20. }
  21. func (b *Builder2) Select2(selects ...interface{}) *Builder2 {
  22. b.Select = selects
  23. return b
  24. }
  25. func (b *Builder2) Sql() (string, error) {
  26. selectSql, err := toSelectSql(b.Select)
  27. if err != nil {
  28. return "", err
  29. }
  30. fromSql, err := toFromSql(b.From)
  31. if err != nil {
  32. return "", err
  33. }
  34. joinSql, err := toJoinSql(b.Join)
  35. if err != nil {
  36. return "", err
  37. }
  38. whereSql, err := toWhereSql(b.Where)
  39. if err != nil {
  40. return "", err
  41. }
  42. groupSql, err := toGroupSql(b.Group)
  43. if err != nil {
  44. return "", err
  45. }
  46. havingSql, err := toHavingSql(b.Having)
  47. if err != nil {
  48. return "", err
  49. }
  50. orderSql, err := toOrderSql(b.Order)
  51. if err != nil {
  52. return "", err
  53. }
  54. sql := fmt.Sprintf("select %s from %s ", selectSql, fromSql)
  55. if joinSql != "" {
  56. sql += fmt.Sprintf(" %s ", joinSql)
  57. }
  58. if whereSql != "" {
  59. sql += fmt.Sprintf(" where %s ", whereSql)
  60. }
  61. if groupSql != "" {
  62. sql += fmt.Sprintf(" group by %s ", groupSql)
  63. }
  64. if havingSql != "" {
  65. sql += fmt.Sprintf(" having %s ", havingSql)
  66. }
  67. if orderSql != "" {
  68. sql += fmt.Sprintf(" order by %s ", orderSql)
  69. }
  70. return sql, nil
  71. }
  72. func toSelectSql(selects interface{}) (string, error) {
  73. selectSql := ""
  74. if selectSql, ok := selects.(string); ok {
  75. return selectSql, nil
  76. }
  77. selectGjson := gjson.Parse(jsonEncode(selects))
  78. if selectGjson.IsArray() {
  79. ses := []string{}
  80. for _, se := range selectGjson.Array() {
  81. ses = append(ses, se.String())
  82. }
  83. selectSql = strings.Join(ses, ",")
  84. } else {
  85. selectSql = selectGjson.String()
  86. }
  87. return selectSql, nil
  88. }
  89. func toFromSql(from interface{}) (string, error) {
  90. fromSql := ""
  91. if fromSql, ok := from.(string); ok {
  92. return fromSql, nil
  93. }
  94. fromGjson := gjson.Parse(jsonEncode(from))
  95. if fromGjson.IsObject() {
  96. nb := NewBuilder2()
  97. json.Unmarshal([]byte(fromGjson.Raw), &nb)
  98. ns, err := nb.Sql()
  99. if err != nil {
  100. return "", err
  101. }
  102. if nb.As != "" {
  103. fromSql = fmt.Sprintf("( %s ) as %s", ns, nb.As)
  104. } else {
  105. fromSql = fmt.Sprintf("( %s )", ns)
  106. }
  107. } else {
  108. fromSql = fromGjson.String()
  109. }
  110. return fromSql, nil
  111. }
  112. func toJoinSql(join interface{}) (string, error) {
  113. if join == nil {
  114. return "", nil
  115. }
  116. // joinSql := ""
  117. if joinSql, ok := join.(string); ok {
  118. return joinSql, nil
  119. }
  120. joinGjson := gjson.Parse(jsonEncode(join))
  121. if joinGjson.IsArray() {
  122. js := []string{}
  123. for _, j := range joinGjson.Array() {
  124. nj, err := toJoinSql(j.Value())
  125. if err != nil {
  126. return "", err
  127. }
  128. js = append(js, nj)
  129. }
  130. return strings.Join(js, " "), nil
  131. } else {
  132. return "", fmt.Errorf("目前仅支持数组或者字符串")
  133. }
  134. // joinGjson := gjson.Parse(jsonEncode(join))
  135. // if joinGjson.IsArray() {
  136. // js := []string{}
  137. // for _, j := range joinGjson.Array() {
  138. // if j.IsObject() {
  139. // return
  140. // } else {
  141. // js = append(js, j.String())
  142. // }
  143. // }
  144. // joinSql = strings.Join(js, " ")
  145. // } else {
  146. // joinSql = joinGjson.String()
  147. // }
  148. // return joinSql
  149. }
  150. func toWhereSql(where interface{}) (string, error) {
  151. if where == nil {
  152. return "", nil
  153. }
  154. whereSql := ""
  155. if whereSql, ok := where.(string); ok {
  156. return whereSql, nil
  157. }
  158. whereGjson := gjson.Parse(jsonEncode(where))
  159. //[ "a=","1","and",[["c=","3"],"and",["d=","4"]],"or",["b=","2"]]
  160. if whereGjson.IsArray() {
  161. ws := []string{}
  162. expression := whereGjson.Array()
  163. if len(expression) == 0 {
  164. return "", nil
  165. }
  166. if expression[0].String() == "and" || expression[0].String() == "or" {
  167. operator := "and"
  168. for _, w := range expression {
  169. if w.Type == gjson.String {
  170. if whereSql == "" && (w.String() == "and" || w.String() == "or") {
  171. operator = w.String()
  172. } else {
  173. ws = append(ws, w.String())
  174. }
  175. } else {
  176. newExp, err := toWhereSql(w.Value())
  177. if err != nil {
  178. return "", err
  179. }
  180. ws = append(ws, newExp)
  181. }
  182. whereSql = strings.Join(ws, fmt.Sprintf(" %s ", operator))
  183. }
  184. } else {
  185. for _, w := range expression {
  186. if w.Type == gjson.String {
  187. ws = append(ws, w.String())
  188. } else {
  189. newExp, err := toWhereSql(w.Value())
  190. if err != nil {
  191. return "", err
  192. }
  193. ws = append(ws, newExp)
  194. }
  195. whereSql = strings.Join(ws, " ")
  196. }
  197. }
  198. } else if whereGjson.IsObject() {
  199. newValue := []interface{}{
  200. "and",
  201. }
  202. ops := []string{"=", ">", ">=", "<", "<=", "<>", "!="}
  203. for k, v := range whereGjson.Map() {
  204. if v.Value() == nil {
  205. continue
  206. }
  207. prefix := k
  208. mop := "="
  209. for _, op := range ops {
  210. if strings.HasSuffix(k, op) {
  211. prefix = strings.TrimSuffix(k, op)
  212. mop = op
  213. break
  214. }
  215. }
  216. newValue = append(newValue, []string{prefix, mop, v.String()})
  217. }
  218. return toWhereSql(newValue)
  219. } else {
  220. whereSql = whereGjson.String()
  221. }
  222. return fmt.Sprintf("( %s )", whereSql), nil
  223. }
  224. func toGroupSql(group interface{}) (string, error) {
  225. if group == nil {
  226. return "", nil
  227. }
  228. // groupSql := ""
  229. if groupSql, ok := group.(string); ok {
  230. return groupSql, nil
  231. }
  232. return "", fmt.Errorf("暂时不支持非字符串类型的group语句")
  233. }
  234. func toHavingSql(having interface{}) (string, error) {
  235. if having == nil {
  236. return "", nil
  237. }
  238. // havingSql := ""
  239. if havingSql, ok := having.(string); ok {
  240. return havingSql, nil
  241. }
  242. return "", fmt.Errorf("暂时不支持非字符串类型的having语句")
  243. }
  244. func toOrderSql(order interface{}) (string, error) {
  245. if order == nil {
  246. return "", nil
  247. }
  248. // orderSql := ""
  249. if orderSql, ok := order.(string); ok {
  250. return orderSql, nil
  251. }
  252. return "", fmt.Errorf("暂时不支持非字符串类型的order语句")
  253. }