gdb_model_join.go 3.1 KB

1234567891011121314151617181920212223242526272829303132333435363738394041424344454647484950515253545556575859606162636465666768697071727374757677787980818283848586878889909192939495
  1. // Copyright GoFrame Author(https://goframe.org). All Rights Reserved.
  2. //
  3. // This Source Code Form is subject to the terms of the MIT License.
  4. // If a copy of the MIT was not distributed with this file,
  5. // You can obtain one at https://github.com/gogf/gf.
  6. package gdb
  7. import (
  8. "fmt"
  9. "github.com/gogf/gf/text/gstr"
  10. )
  11. // isSubQuery checks and returns whether given string a sub-query sql string.
  12. func isSubQuery(s string) bool {
  13. s = gstr.TrimLeft(s, "()")
  14. if p := gstr.Pos(s, " "); p != -1 {
  15. if gstr.Equal(s[:p], "select") {
  16. return true
  17. }
  18. }
  19. return false
  20. }
  21. // LeftJoin does "LEFT JOIN ... ON ..." statement on the model.
  22. // The parameter `table` can be joined table and its joined condition,
  23. // and also with its alias name, like:
  24. // Table("user").LeftJoin("user_detail", "user_detail.uid=user.uid")
  25. // Table("user", "u").LeftJoin("user_detail", "ud", "ud.uid=u.uid")
  26. // Table("user", "u").LeftJoin("SELECT xxx FROM xxx AS a", "a.uid=u.uid")
  27. func (m *Model) LeftJoin(table ...string) *Model {
  28. return m.doJoin("LEFT", table...)
  29. }
  30. // RightJoin does "RIGHT JOIN ... ON ..." statement on the model.
  31. // The parameter `table` can be joined table and its joined condition,
  32. // and also with its alias name, like:
  33. // Table("user").RightJoin("user_detail", "user_detail.uid=user.uid")
  34. // Table("user", "u").RightJoin("user_detail", "ud", "ud.uid=u.uid")
  35. // Table("user", "u").RightJoin("SELECT xxx FROM xxx AS a", "a.uid=u.uid")
  36. func (m *Model) RightJoin(table ...string) *Model {
  37. return m.doJoin("RIGHT", table...)
  38. }
  39. // InnerJoin does "INNER JOIN ... ON ..." statement on the model.
  40. // The parameter `table` can be joined table and its joined condition,
  41. // and also with its alias name, like:
  42. // Table("user").InnerJoin("user_detail", "user_detail.uid=user.uid")
  43. // Table("user", "u").InnerJoin("user_detail", "ud", "ud.uid=u.uid")
  44. // Table("user", "u").InnerJoin("SELECT xxx FROM xxx AS a", "a.uid=u.uid")
  45. func (m *Model) InnerJoin(table ...string) *Model {
  46. return m.doJoin("INNER", table...)
  47. }
  48. // doJoin does "LEFT/RIGHT/INNER JOIN ... ON ..." statement on the model.
  49. // The parameter `table` can be joined table and its joined condition,
  50. // and also with its alias name, like:
  51. // Model("user").InnerJoin("user_detail", "user_detail.uid=user.uid")
  52. // Model("user", "u").InnerJoin("user_detail", "ud", "ud.uid=u.uid")
  53. // Model("user", "u").InnerJoin("SELECT xxx FROM xxx AS a", "a.uid=u.uid")
  54. // Related issues:
  55. // https://github.com/gogf/gf/issues/1024
  56. func (m *Model) doJoin(operator string, table ...string) *Model {
  57. var (
  58. model = m.getModel()
  59. joinStr = ""
  60. )
  61. if len(table) > 0 {
  62. if isSubQuery(table[0]) {
  63. joinStr = gstr.Trim(table[0])
  64. if joinStr[0] != '(' {
  65. joinStr = "(" + joinStr + ")"
  66. }
  67. } else {
  68. joinStr = m.db.GetCore().QuotePrefixTableName(table[0])
  69. }
  70. }
  71. if len(table) > 2 {
  72. model.tables += fmt.Sprintf(
  73. " %s JOIN %s AS %s ON (%s)",
  74. operator, joinStr, m.db.GetCore().QuoteWord(table[1]), table[2],
  75. )
  76. } else if len(table) == 2 {
  77. model.tables += fmt.Sprintf(
  78. " %s JOIN %s ON (%s)",
  79. operator, joinStr, table[1],
  80. )
  81. } else if len(table) == 1 {
  82. model.tables += fmt.Sprintf(
  83. " %s JOIN %s", operator, joinStr,
  84. )
  85. }
  86. return model
  87. }