github.com/gogf/gf@v1.16.9/database/gdb/gdb_model_join.go (about) 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 7 package gdb 8 9 import ( 10 "fmt" 11 12 "github.com/gogf/gf/text/gstr" 13 ) 14 15 // isSubQuery checks and returns whether given string a sub-query sql string. 16 func isSubQuery(s string) bool { 17 s = gstr.TrimLeft(s, "()") 18 if p := gstr.Pos(s, " "); p != -1 { 19 if gstr.Equal(s[:p], "select") { 20 return true 21 } 22 } 23 return false 24 } 25 26 // LeftJoin does "LEFT JOIN ... ON ..." statement on the model. 27 // The parameter `table` can be joined table and its joined condition, 28 // and also with its alias name, like: 29 // Table("user").LeftJoin("user_detail", "user_detail.uid=user.uid") 30 // Table("user", "u").LeftJoin("user_detail", "ud", "ud.uid=u.uid") 31 // Table("user", "u").LeftJoin("SELECT xxx FROM xxx AS a", "a.uid=u.uid") 32 func (m *Model) LeftJoin(table ...string) *Model { 33 return m.doJoin("LEFT", table...) 34 } 35 36 // RightJoin does "RIGHT JOIN ... ON ..." statement on the model. 37 // The parameter `table` can be joined table and its joined condition, 38 // and also with its alias name, like: 39 // Table("user").RightJoin("user_detail", "user_detail.uid=user.uid") 40 // Table("user", "u").RightJoin("user_detail", "ud", "ud.uid=u.uid") 41 // Table("user", "u").RightJoin("SELECT xxx FROM xxx AS a", "a.uid=u.uid") 42 func (m *Model) RightJoin(table ...string) *Model { 43 return m.doJoin("RIGHT", table...) 44 } 45 46 // InnerJoin does "INNER JOIN ... ON ..." statement on the model. 47 // The parameter `table` can be joined table and its joined condition, 48 // and also with its alias name, like: 49 // Table("user").InnerJoin("user_detail", "user_detail.uid=user.uid") 50 // Table("user", "u").InnerJoin("user_detail", "ud", "ud.uid=u.uid") 51 // Table("user", "u").InnerJoin("SELECT xxx FROM xxx AS a", "a.uid=u.uid") 52 func (m *Model) InnerJoin(table ...string) *Model { 53 return m.doJoin("INNER", table...) 54 } 55 56 // doJoin does "LEFT/RIGHT/INNER JOIN ... ON ..." statement on the model. 57 // The parameter `table` can be joined table and its joined condition, 58 // and also with its alias name, like: 59 // Model("user").InnerJoin("user_detail", "user_detail.uid=user.uid") 60 // Model("user", "u").InnerJoin("user_detail", "ud", "ud.uid=u.uid") 61 // Model("user", "u").InnerJoin("SELECT xxx FROM xxx AS a", "a.uid=u.uid") 62 // Related issues: 63 // https://github.com/gogf/gf/issues/1024 64 func (m *Model) doJoin(operator string, table ...string) *Model { 65 var ( 66 model = m.getModel() 67 joinStr = "" 68 ) 69 if len(table) > 0 { 70 if isSubQuery(table[0]) { 71 joinStr = gstr.Trim(table[0]) 72 if joinStr[0] != '(' { 73 joinStr = "(" + joinStr + ")" 74 } 75 } else { 76 joinStr = m.db.GetCore().QuotePrefixTableName(table[0]) 77 } 78 } 79 if len(table) > 2 { 80 model.tables += fmt.Sprintf( 81 " %s JOIN %s AS %s ON (%s)", 82 operator, joinStr, m.db.GetCore().QuoteWord(table[1]), table[2], 83 ) 84 } else if len(table) == 2 { 85 model.tables += fmt.Sprintf( 86 " %s JOIN %s ON (%s)", 87 operator, joinStr, table[1], 88 ) 89 } else if len(table) == 1 { 90 model.tables += fmt.Sprintf( 91 " %s JOIN %s", operator, joinStr, 92 ) 93 } 94 return model 95 }