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.

757 lines
18 KiB

2 years ago
2 years ago
2 years ago
2 years ago
2 years ago
2 years ago
2 years ago
2 years ago
2 years ago
2 years ago
2 years ago
2 years ago
2 years ago
2 years ago
2 years ago
2 years ago
2 years ago
2 years ago
2 years ago
2 years ago
2 years ago
  1. package vql
  2. import (
  3. "encoding/json"
  4. "fmt"
  5. "log"
  6. "reflect"
  7. "strings"
  8. "git.ouxuan.net/3136352472/vql/builder"
  9. "github.com/spf13/cast"
  10. "github.com/xwb1989/sqlparser"
  11. )
  12. type CondType string
  13. const (
  14. CondTypeCondition CondType = "condition"
  15. CondTypeAnd CondType = "and"
  16. CondTypeOr CondType = "or"
  17. )
  18. type FieldValue struct {
  19. Type string `json:"type"` // field, value
  20. Field *Field `json:"field,omitempty"`
  21. Value string `json:"value,omitempty"`
  22. }
  23. type WhereCondition struct {
  24. Condition string `json:"condition"`
  25. Left FieldValue `json:"left"`
  26. Right FieldValue `json:"right"`
  27. }
  28. type Where struct {
  29. Cond CondType `json:"cond"`
  30. Sub []Where `json:"sub,omitempty"`
  31. Value *WhereCondition `json:"value,omitempty"`
  32. }
  33. func (w *Where) ToCond() (builder.Cond, error) {
  34. var cond builder.Cond
  35. if w.Cond != CondTypeCondition {
  36. var conds []builder.Cond
  37. for _, v := range w.Sub {
  38. subCond, err := v.ToCond()
  39. if err != nil {
  40. return nil, err
  41. }
  42. conds = append(conds, subCond)
  43. }
  44. switch w.Cond {
  45. case CondTypeAnd:
  46. cond = builder.And(conds...)
  47. case CondTypeOr:
  48. cond = builder.Or(conds...)
  49. }
  50. } else {
  51. l := ""
  52. if w.Value.Left.Type == "field" {
  53. l = w.Value.Left.Field.Name
  54. if w.Value.Left.Field.FromTable != "" {
  55. l = fmt.Sprint(w.Value.Left.Field.FromTable, ".", l)
  56. }
  57. } else {
  58. l = w.Value.Left.Value
  59. }
  60. var r interface{}
  61. if w.Value.Right.Type == "field" {
  62. r = w.Value.Right.Field.Name
  63. if w.Value.Right.Field.FromTable != "" {
  64. r = builder.Field(fmt.Sprint(w.Value.Right.Field.FromTable, ".", r))
  65. }
  66. } else {
  67. r = w.Value.Right.Value
  68. }
  69. switch w.Value.Condition {
  70. case "eq", "equal", "=":
  71. cond = builder.Eq{l: r}
  72. case "neq", "not equal", "!=":
  73. cond = builder.Neq{l: r}
  74. case "gt", "greater than", ">":
  75. cond = builder.Gt{l: r}
  76. case "gte", "greater than or equal", ">=":
  77. cond = builder.Gte{l: r}
  78. case "lt", "less than", "<":
  79. cond = builder.Lt{l: r}
  80. case "lte", "less than or equal", "<=":
  81. cond = builder.Lte{l: r}
  82. case "like":
  83. cond = builder.Like{l, fmt.Sprint(r)}
  84. case "not like":
  85. cond = builder.Like{fmt.Sprint(l, " not"), fmt.Sprint(r)}
  86. case "in":
  87. cond = builder.In(l, r)
  88. case "not in":
  89. cond = builder.NotIn(l, r)
  90. default:
  91. return nil, fmt.Errorf("unknown condition: %s", w.Value.Condition)
  92. }
  93. }
  94. return cond, nil
  95. }
  96. func (w *Where) FromSql(sql string) error {
  97. stmt, err := sqlparser.Parse(sql)
  98. if err != nil {
  99. return err
  100. }
  101. switch stmt.(type) {
  102. case *sqlparser.Select:
  103. sel := stmt.(*sqlparser.Select)
  104. if sel.Where != nil {
  105. return w.fromExpr(sel.Where.Expr)
  106. }
  107. }
  108. return nil
  109. }
  110. func (w *Where) fromExpr(expr sqlparser.Expr) error {
  111. // log.Println("expr:", reflect.TypeOf(expr), jsonEncode(expr))
  112. switch expr.(type) {
  113. case *sqlparser.AndExpr:
  114. var left, right Where
  115. w.Cond = CondTypeAnd
  116. and := expr.(*sqlparser.AndExpr)
  117. if err := left.fromExpr(and.Left); err != nil {
  118. return err
  119. }
  120. w.Sub = append(w.Sub, left)
  121. if err := right.fromExpr(and.Right); err != nil {
  122. return err
  123. }
  124. w.Sub = append(w.Sub, right)
  125. case *sqlparser.OrExpr:
  126. var left, right Where
  127. w.Cond = CondTypeOr
  128. or := expr.(*sqlparser.OrExpr)
  129. if err := left.fromExpr(or.Left); err != nil {
  130. return err
  131. }
  132. w.Sub = append(w.Sub, left)
  133. if err := right.fromExpr(or.Right); err != nil {
  134. return err
  135. }
  136. w.Sub = append(w.Sub, right)
  137. case *sqlparser.ParenExpr:
  138. paren := expr.(*sqlparser.ParenExpr)
  139. if err := w.fromExpr(paren.Expr); err != nil {
  140. return err
  141. }
  142. case *sqlparser.ComparisonExpr:
  143. w.Cond = CondTypeCondition
  144. return w.conditionExpr(expr)
  145. default:
  146. return fmt.Errorf("unknown expr: %s", reflect.TypeOf(expr))
  147. log.Println("unknown expr:", reflect.TypeOf(expr), jsonEncode(expr))
  148. }
  149. return nil
  150. }
  151. func (w *Where) conditionExpr(expr sqlparser.Expr) error {
  152. // log.Println("conditionExpr:", reflect.TypeOf(expr), jsonEncode(expr))
  153. switch expr.(type) {
  154. case *sqlparser.ComparisonExpr:
  155. comp := expr.(*sqlparser.ComparisonExpr)
  156. w.Value = &WhereCondition{}
  157. w.Value.Condition = "unknown"
  158. switch comp.Operator {
  159. case "=":
  160. w.Value.Condition = "eq"
  161. case "!=":
  162. w.Value.Condition = "neq"
  163. case ">":
  164. w.Value.Condition = "gt"
  165. case ">=":
  166. w.Value.Condition = "gte"
  167. case "<":
  168. w.Value.Condition = "lt"
  169. case "<=":
  170. w.Value.Condition = "lte"
  171. case "like":
  172. w.Value.Condition = "like"
  173. case "not like":
  174. w.Value.Condition = "not like"
  175. case "in":
  176. w.Value.Condition = "in"
  177. case "not in":
  178. w.Value.Condition = "not in"
  179. default:
  180. return fmt.Errorf("unknown operator: %s", comp.Operator)
  181. }
  182. if leftCol, ok := comp.Left.(*sqlparser.ColName); ok {
  183. w.Value.Left = FieldValue{
  184. Type: "field",
  185. Field: &Field{
  186. Name: string(leftCol.Name.String()),
  187. FromTable: string(leftCol.Qualifier.Name.String()),
  188. },
  189. }
  190. } else if leftVal, ok := comp.Left.(*sqlparser.SQLVal); ok {
  191. w.Value.Left = FieldValue{
  192. Type: "value",
  193. Value: string(leftVal.Val),
  194. }
  195. } else {
  196. return fmt.Errorf("unexpected left type: %T", comp.Left)
  197. }
  198. if rightCol, ok := comp.Right.(*sqlparser.ColName); ok {
  199. w.Value.Right = FieldValue{
  200. Type: "field",
  201. Field: &Field{
  202. Name: string(rightCol.Name.String()),
  203. FromTable: string(rightCol.Qualifier.Name.String()),
  204. },
  205. }
  206. } else if rightVal, ok := comp.Right.(*sqlparser.SQLVal); ok {
  207. w.Value.Right = FieldValue{
  208. Type: "value",
  209. Value: string(rightVal.Val),
  210. }
  211. } else {
  212. return fmt.Errorf("unexpected right type: %T", comp.Right)
  213. }
  214. default:
  215. return fmt.Errorf("unexpected type: %T", expr)
  216. }
  217. // log.Println("Where:", w)
  218. return nil
  219. }
  220. func (w *Where) FromCond(cond builder.Cond) error {
  221. if cond == nil {
  222. return fmt.Errorf("condition is nil")
  223. }
  224. switch builder.CondType(cond) {
  225. case "and":
  226. w.Cond = CondTypeAnd
  227. condAnd := builder.GetCondAnd(cond)
  228. for _, v := range condAnd {
  229. var sub Where
  230. sub.FromCond(v)
  231. w.Sub = append(w.Sub, sub)
  232. }
  233. case "or":
  234. w.Cond = CondTypeOr
  235. condOr := builder.GetCondOr(cond)
  236. for _, v := range condOr {
  237. var sub Where
  238. sub.FromCond(v)
  239. w.Sub = append(w.Sub, sub)
  240. }
  241. default:
  242. w.Cond = "condition"
  243. err := w.condition(cond)
  244. if err != nil {
  245. return err
  246. }
  247. }
  248. return nil
  249. }
  250. func (w *Where) condition(cond builder.Cond) error {
  251. condMap := map[string]interface{}{}
  252. json.Unmarshal([]byte(jsonEncode(cond)), &condMap)
  253. conditionName := ""
  254. switch cond.(type) {
  255. case builder.Eq:
  256. conditionName = "eq"
  257. case builder.Neq:
  258. conditionName = "neq"
  259. case builder.Gt:
  260. conditionName = "gt"
  261. case builder.Gte:
  262. conditionName = "gte"
  263. case builder.Lt:
  264. conditionName = "lt"
  265. case builder.Lte:
  266. conditionName = "lte"
  267. case builder.Like:
  268. conditionName = "like"
  269. case builder.Between:
  270. conditionName = "between"
  271. default:
  272. ct := builder.CondType(cond)
  273. if ct == "in" {
  274. conditionName = "in"
  275. } else if ct == "not in" {
  276. conditionName = "not in"
  277. } else {
  278. return fmt.Errorf("condition type %s not support", ct)
  279. }
  280. }
  281. if len(condMap) > 1 {
  282. w.Cond = CondTypeCondition
  283. for k, v := range condMap {
  284. var sub Where
  285. sub.Value = &WhereCondition{
  286. Condition: conditionName,
  287. Left: FieldValue{
  288. Type: "value",
  289. Value: k,
  290. },
  291. Right: FieldValue{
  292. Type: "value",
  293. Value: fmt.Sprint(v),
  294. },
  295. }
  296. w.Sub = append(w.Sub, sub)
  297. }
  298. } else {
  299. w.Value = &WhereCondition{
  300. Condition: conditionName,
  301. }
  302. for k, v := range condMap {
  303. w.Value.Left = FieldValue{
  304. Type: "value",
  305. Value: k,
  306. }
  307. w.Value.Right = FieldValue{
  308. Type: "value",
  309. Value: fmt.Sprint(v),
  310. }
  311. }
  312. }
  313. return nil
  314. }
  315. type Field struct {
  316. FromTable string `json:"from_table"`
  317. Name string `json:"name"`
  318. As string `json:"as"`
  319. }
  320. type From struct {
  321. Table string `json:"table"`
  322. SubQuery *Query `json:"sub_query,omitempty"`
  323. raw string `json:"-"`
  324. As string `json:"as"`
  325. }
  326. type Join struct {
  327. Type string `json:"type"`
  328. Query *Query `json:"query"`
  329. JoinWhere *Where `json:"join_where,omitempty"`
  330. }
  331. type Limit struct {
  332. Offset int `json:"offset"`
  333. Count int `json:"count"`
  334. }
  335. type OrderByField struct {
  336. Field Field `json:"field"`
  337. Direction string `json:"desc"`
  338. }
  339. type Query struct {
  340. Dialect DialectType `json:"dialect"`
  341. From From `json:"from"`
  342. Join []Join `json:"join,omitempty"`
  343. Fields []Field `json:"field,omitempty"`
  344. Where *Where `json:"where,omitempty"`
  345. GroupBy []Field `json:"group_by,omitempty"`
  346. Having string `json:"having,omitempty"`
  347. OrderBy []OrderByField `json:"order_by,omitempty"`
  348. Limit *Limit `json:"limit,omitempty"`
  349. }
  350. func getTheLeftmost(node *sqlparser.JoinTableExpr) (left *sqlparser.AliasedTableExpr) {
  351. if node.LeftExpr == nil {
  352. return nil
  353. }
  354. switch left := node.LeftExpr.(type) {
  355. case *sqlparser.AliasedTableExpr:
  356. return left
  357. case *sqlparser.JoinTableExpr:
  358. return getTheLeftmost(left)
  359. default:
  360. return nil
  361. }
  362. }
  363. func nodeExtractRawSQL(node sqlparser.SQLNode) string {
  364. buff := sqlparser.NewTrackedBuffer(nil)
  365. node.Format(buff)
  366. return buff.String()
  367. }
  368. func (q *Query) FromSelect(selectStmt *sqlparser.Select) error {
  369. if selectStmt == nil {
  370. return fmt.Errorf("selectStmt is nil")
  371. }
  372. if selectStmt.SelectExprs != nil {
  373. for _, v := range selectStmt.SelectExprs {
  374. switch expr := v.(type) {
  375. case *sqlparser.StarExpr:
  376. // log.Println("selectStmt.StarExpr", reflect.TypeOf(expr), jsonEncode(expr))
  377. q.Fields = append(q.Fields, Field{
  378. Name: "*",
  379. FromTable: expr.TableName.Name.String(),
  380. })
  381. case *sqlparser.AliasedExpr:
  382. // log.Println("selectStmt.AliasedExpr", reflect.TypeOf(expr.Expr), jsonEncode(expr.Expr))
  383. switch colName := expr.Expr.(type) {
  384. case *sqlparser.ColName:
  385. q.Fields = append(q.Fields, Field{
  386. FromTable: colName.Qualifier.Name.String(),
  387. Name: string(colName.Name.String()),
  388. As: expr.As.String(),
  389. })
  390. case *sqlparser.FuncExpr:
  391. name := nodeExtractRawSQL(colName)
  392. q.Fields = append(q.Fields, Field{
  393. Name: name,
  394. As: expr.As.String(),
  395. })
  396. }
  397. }
  398. }
  399. }
  400. if selectStmt.Where != nil {
  401. if q.Where == nil {
  402. q.Where = &Where{}
  403. }
  404. if err := q.Where.fromExpr(selectStmt.Where.Expr); err != nil {
  405. return err
  406. }
  407. }
  408. if selectStmt.From != nil {
  409. if len(selectStmt.From) > 1 {
  410. return fmt.Errorf("not support multi table")
  411. }
  412. form := selectStmt.From[0]
  413. switch form := form.(type) {
  414. case *sqlparser.AliasedTableExpr: //未联表
  415. if form.As.String() != "" {
  416. q.From.As = form.As.String()
  417. }
  418. switch exp := form.Expr.(type) {
  419. case sqlparser.TableName:
  420. // log.Println("TableName:", jsonEncode(exp))
  421. q.From.Table = string(exp.Name.String())
  422. case *sqlparser.Subquery:
  423. subQuery := &Query{}
  424. if err := subQuery.FromSelect(exp.Select.(*sqlparser.Select)); err != nil {
  425. return err
  426. }
  427. q.From.SubQuery = subQuery
  428. }
  429. case *sqlparser.JoinTableExpr: //有联表
  430. // log.Println("JoinTableExpr:", jsonEncode(form))
  431. //确定主表
  432. leftmost := getTheLeftmost(form)
  433. if leftmost != nil {
  434. // log.Println("leftmost:", jsonEncode(leftmost))
  435. if leftmost.As.String() != "" {
  436. q.From.As = leftmost.As.String()
  437. }
  438. switch leftmostExpr := leftmost.Expr.(type) {
  439. case sqlparser.TableName:
  440. q.From.Table = string(leftmostExpr.Name.String())
  441. case *sqlparser.Subquery:
  442. subQuery := &Query{}
  443. if err := subQuery.FromSelect(leftmostExpr.Select.(*sqlparser.Select)); err != nil {
  444. return err
  445. }
  446. q.From.SubQuery = subQuery
  447. }
  448. } else {
  449. //找不到最左边的表
  450. return fmt.Errorf("can not find the leftmost table")
  451. }
  452. //确定联表
  453. for {
  454. if form == nil {
  455. break
  456. }
  457. join := Join{
  458. Type: strings.ToUpper(strings.Trim(strings.TrimSuffix(strings.Trim(strings.ToLower(form.Join), " "), "join"), " ")),
  459. }
  460. switch right := form.RightExpr.(type) {
  461. case *sqlparser.AliasedTableExpr:
  462. join.Query = &Query{}
  463. if right.As.String() != "" {
  464. join.Query.From.As = right.As.String()
  465. }
  466. switch rightExpr := right.Expr.(type) {
  467. case sqlparser.TableName:
  468. // log.Println("rightExpr:", jsonEncode(rightExpr))
  469. join.Query.From.Table = string(rightExpr.Name.String())
  470. case *sqlparser.Subquery:
  471. subQuery := &Query{}
  472. if err := subQuery.FromSelect(rightExpr.Select.(*sqlparser.Select)); err != nil {
  473. return err
  474. }
  475. join.Query.From.SubQuery = subQuery
  476. }
  477. }
  478. join.JoinWhere = &Where{}
  479. if err := join.JoinWhere.fromExpr(form.Condition.On); err != nil {
  480. return err
  481. }
  482. q.Join = append(q.Join, join)
  483. var ok bool
  484. form, ok = form.LeftExpr.(*sqlparser.JoinTableExpr)
  485. if !ok {
  486. break
  487. }
  488. }
  489. }
  490. // log.Println("selectStmt.From:", reflect.TypeOf(selectStmt.From), jsonEncode(selectStmt.From))
  491. }
  492. if selectStmt.GroupBy != nil {
  493. // log.Println("selectStmt.GroupBy:", reflect.TypeOf(selectStmt.GroupBy), jsonEncode(selectStmt.GroupBy))
  494. for _, v := range selectStmt.GroupBy {
  495. switch colName := v.(type) {
  496. case *sqlparser.ColName:
  497. q.GroupBy = append(q.GroupBy, Field{
  498. FromTable: colName.Qualifier.Name.String(),
  499. Name: string(colName.Name.String()),
  500. })
  501. }
  502. }
  503. }
  504. if selectStmt.OrderBy != nil {
  505. // log.Println("selectStmt.OrderBy:", reflect.TypeOf(selectStmt.OrderBy), jsonEncode(selectStmt.OrderBy))
  506. for _, v := range selectStmt.OrderBy {
  507. switch colName := v.Expr.(type) {
  508. case *sqlparser.ColName:
  509. q.OrderBy = append(q.OrderBy, OrderByField{
  510. Field: Field{
  511. FromTable: colName.Qualifier.Name.String(),
  512. Name: string(colName.Name.String()),
  513. },
  514. Direction: v.Direction,
  515. })
  516. }
  517. }
  518. }
  519. if selectStmt.Having != nil {
  520. // log.Println("selectStmt.Having:", reflect.TypeOf(selectStmt.Having), jsonEncode(selectStmt.Having))
  521. q.Having = nodeExtractRawSQL(selectStmt.Having.Expr)
  522. }
  523. if selectStmt.Limit != nil {
  524. // log.Println("selectStmt.Limit:", jsonEncode(selectStmt.Limit))
  525. if q.Limit == nil {
  526. q.Limit = &Limit{}
  527. }
  528. switch offset := selectStmt.Limit.Offset.(type) {
  529. case *sqlparser.SQLVal:
  530. q.Limit.Offset = cast.ToInt(fmt.Sprintf("%s", offset.Val))
  531. }
  532. switch count := selectStmt.Limit.Rowcount.(type) {
  533. case *sqlparser.SQLVal:
  534. q.Limit.Count = cast.ToInt(fmt.Sprintf("%s", count.Val))
  535. }
  536. }
  537. // log.Println("query:", jsonEncode(q))
  538. return nil
  539. }
  540. func (q *Query) FromSql(sql string) error {
  541. stmt, err := sqlparser.Parse(sql)
  542. if err != nil {
  543. return err
  544. }
  545. switch stmt.(type) {
  546. case *sqlparser.Select:
  547. selectStmt := stmt.(*sqlparser.Select)
  548. return q.FromSelect(selectStmt)
  549. default:
  550. return fmt.Errorf("unexpected type: %T", stmt)
  551. }
  552. }
  553. type DialectType string
  554. const (
  555. POSTGRES DialectType = "postgres"
  556. SQLITE = "sqlite3"
  557. MYSQL = "mysql"
  558. MSSQL = "mssql"
  559. ORACLE = "oracle"
  560. UNION = "union"
  561. INTERSECT = "intersect"
  562. EXCEPT = "except"
  563. )
  564. func (q *Query) ToBuilder() (*builder.Builder, error) {
  565. var dialect DialectType = MYSQL
  566. if q.Dialect != "" {
  567. dialect = q.Dialect
  568. }
  569. fields := []string{}
  570. for i := range q.Fields {
  571. name := q.Fields[i].Name
  572. if q.Fields[i].FromTable != "" {
  573. name = fmt.Sprintf("%s.`%s`", q.Fields[i].FromTable, name)
  574. }
  575. if q.Fields[i].As != "" {
  576. name = fmt.Sprintf("%s AS %s", name, q.Fields[i].As)
  577. }
  578. fields = append(fields, name)
  579. }
  580. b := builder.Dialect(string(dialect)).Select(fields...)
  581. if q.From.raw != "" {
  582. if q.From.As != "" {
  583. b = b.From(fmt.Sprintf("(%s)", q.From.raw), q.From.As)
  584. } else {
  585. b = b.From(fmt.Sprintf("(%s)", q.From.raw))
  586. }
  587. } else if q.From.Table != "" {
  588. if q.From.As != "" {
  589. b = b.From(q.From.Table, q.From.As)
  590. } else {
  591. b = b.From(q.From.Table)
  592. }
  593. } else {
  594. if q.From.SubQuery != nil {
  595. subBuilder, err := q.From.SubQuery.ToBuilder()
  596. if err != nil {
  597. return nil, err
  598. }
  599. if q.From.As != "" {
  600. b = b.From(subBuilder, q.From.As)
  601. } else {
  602. b = b.From(subBuilder)
  603. }
  604. }
  605. }
  606. if q.Join != nil {
  607. for _, join := range q.Join {
  608. if join.Query != nil {
  609. // log.Println("join:", jsonEncode(join))
  610. if join.Query.From.As == "" {
  611. return nil, fmt.Errorf("join table must have an alias")
  612. }
  613. if join.Query.From.raw != "" {
  614. cond, err := join.JoinWhere.ToCond()
  615. if err != nil {
  616. return nil, err
  617. }
  618. b = b.Join(join.Type, fmt.Sprintf("(%s)", join.Query.From.raw), cond, join.Query.From.As)
  619. } else if join.Query.From.SubQuery != nil {
  620. subBuilder, err := join.Query.From.SubQuery.ToBuilder()
  621. if err != nil {
  622. return nil, err
  623. }
  624. cond, err := join.JoinWhere.ToCond()
  625. if err != nil {
  626. return nil, err
  627. }
  628. b = b.Join(join.Type, subBuilder, cond, join.Query.From.As)
  629. } else {
  630. cond, err := join.JoinWhere.ToCond()
  631. if err != nil {
  632. return nil, err
  633. }
  634. b = b.Join(join.Type, join.Query.From.Table, cond, join.Query.From.As)
  635. }
  636. }
  637. }
  638. }
  639. if q.GroupBy != nil {
  640. groupBy := []string{}
  641. for i := range q.GroupBy {
  642. name := q.GroupBy[i].Name
  643. if q.GroupBy[i].FromTable != "" {
  644. name = fmt.Sprintf("%s.`%s`", q.GroupBy[i].FromTable, name)
  645. }
  646. groupBy = append(groupBy, name)
  647. }
  648. b = b.GroupBy(fmt.Sprintf("( %s )", strings.Join(groupBy, ", ")))
  649. }
  650. if q.OrderBy != nil {
  651. orderBy := []string{}
  652. for i := range q.OrderBy {
  653. name := q.OrderBy[i].Field.Name
  654. if q.OrderBy[i].Field.FromTable != "" {
  655. name = fmt.Sprintf("%s.`%s`", q.OrderBy[i].Field.FromTable, name)
  656. }
  657. if q.OrderBy[i].Direction != "" {
  658. name = fmt.Sprintf("%s %s", name, q.OrderBy[i].Direction)
  659. }
  660. orderBy = append(orderBy, name)
  661. }
  662. b = b.OrderBy(fmt.Sprintf("%s", strings.Join(orderBy, ", ")))
  663. }
  664. if q.Where != nil {
  665. cond, err := q.Where.ToCond()
  666. if err != nil {
  667. return nil, err
  668. }
  669. b = b.Where(cond)
  670. }
  671. if q.Having != "" {
  672. b = b.Having(q.Having)
  673. }
  674. if q.Limit != nil {
  675. b = b.Limit(q.Limit.Count, q.Limit.Offset)
  676. }
  677. return b, nil
  678. }
  679. func (q *Query) ToSql() (string, error) {
  680. b, err := q.ToBuilder()
  681. if err != nil {
  682. return "", fmt.Errorf("failed to build query: %w", err)
  683. }
  684. return b.ToBoundSQL()
  685. }