github.com/mdaxf/iac@v0.0.0-20240519030858-58a061660378/databases/orm/qb_postgres.go (about) 1 // The original package is migrated from beego and modified, you can find orignal from following link: 2 // "github.com/beego/beego/" 3 // 4 // Copyright 2023 IAC. All Rights Reserved. 5 // 6 // Licensed under the Apache License, Version 2.0 (the "License"); 7 // you may not use this file except in compliance with the License. 8 // You may obtain a copy of the License at 9 // 10 // http://www.apache.org/licenses/LICENSE-2.0 11 // 12 // Unless required by applicable law or agreed to in writing, software 13 // distributed under the License is distributed on an "AS IS" BASIS, 14 // WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. 15 // See the License for the specific language governing permissions and 16 // limitations under the License. 17 18 package orm 19 20 import ( 21 "fmt" 22 "strconv" 23 "strings" 24 ) 25 26 var quote string = `"` 27 28 // PostgresQueryBuilder is the SQL build 29 type PostgresQueryBuilder struct { 30 tokens []string 31 } 32 33 func processingStr(str []string) string { 34 s := strings.Join(str, `","`) 35 s = fmt.Sprintf("%s%s%s", quote, s, quote) 36 return s 37 } 38 39 // Select will join the fields 40 func (qb *PostgresQueryBuilder) Select(fields ...string) QueryBuilder { 41 var str string 42 n := len(fields) 43 44 if fields[0] == "*" { 45 str = "*" 46 } else { 47 for i := 0; i < n; i++ { 48 sli := strings.Split(fields[i], ".") 49 s := strings.Join(sli, `"."`) 50 s = fmt.Sprintf("%s%s%s", quote, s, quote) 51 if n == 1 || i == n-1 { 52 str += s 53 } else { 54 str += s + "," 55 } 56 } 57 } 58 59 qb.tokens = append(qb.tokens, "SELECT", str) 60 return qb 61 } 62 63 // ForUpdate add the FOR UPDATE clause 64 func (qb *PostgresQueryBuilder) ForUpdate() QueryBuilder { 65 qb.tokens = append(qb.tokens, "FOR UPDATE") 66 return qb 67 } 68 69 // From join the tables 70 func (qb *PostgresQueryBuilder) From(tables ...string) QueryBuilder { 71 str := processingStr(tables) 72 qb.tokens = append(qb.tokens, "FROM", str) 73 return qb 74 } 75 76 // InnerJoin INNER JOIN the table 77 func (qb *PostgresQueryBuilder) InnerJoin(table string) QueryBuilder { 78 str := fmt.Sprintf("%s%s%s", quote, table, quote) 79 qb.tokens = append(qb.tokens, "INNER JOIN", str) 80 return qb 81 } 82 83 // LeftJoin LEFT JOIN the table 84 func (qb *PostgresQueryBuilder) LeftJoin(table string) QueryBuilder { 85 str := fmt.Sprintf("%s%s%s", quote, table, quote) 86 qb.tokens = append(qb.tokens, "LEFT JOIN", str) 87 return qb 88 } 89 90 // RightJoin RIGHT JOIN the table 91 func (qb *PostgresQueryBuilder) RightJoin(table string) QueryBuilder { 92 str := fmt.Sprintf("%s%s%s", quote, table, quote) 93 qb.tokens = append(qb.tokens, "RIGHT JOIN", str) 94 return qb 95 } 96 97 // On join with on cond 98 func (qb *PostgresQueryBuilder) On(cond string) QueryBuilder { 99 var str string 100 cond = strings.Replace(cond, " ", "", -1) 101 slice := strings.Split(cond, "=") 102 for i := 0; i < len(slice); i++ { 103 sli := strings.Split(slice[i], ".") 104 s := strings.Join(sli, `"."`) 105 s = fmt.Sprintf("%s%s%s", quote, s, quote) 106 if i == 0 { 107 str = s + " =" + " " 108 } else { 109 str += s 110 } 111 } 112 113 qb.tokens = append(qb.tokens, "ON", str) 114 return qb 115 } 116 117 // Where join the Where cond 118 func (qb *PostgresQueryBuilder) Where(cond string) QueryBuilder { 119 qb.tokens = append(qb.tokens, "WHERE", cond) 120 return qb 121 } 122 123 // And join the and cond 124 func (qb *PostgresQueryBuilder) And(cond string) QueryBuilder { 125 qb.tokens = append(qb.tokens, "AND", cond) 126 return qb 127 } 128 129 // Or join the or cond 130 func (qb *PostgresQueryBuilder) Or(cond string) QueryBuilder { 131 qb.tokens = append(qb.tokens, "OR", cond) 132 return qb 133 } 134 135 // In join the IN (vals) 136 func (qb *PostgresQueryBuilder) In(vals ...string) QueryBuilder { 137 qb.tokens = append(qb.tokens, "IN", "(", strings.Join(vals, CommaSpace), ")") 138 return qb 139 } 140 141 // OrderBy join the Order by fields 142 func (qb *PostgresQueryBuilder) OrderBy(fields ...string) QueryBuilder { 143 str := processingStr(fields) 144 qb.tokens = append(qb.tokens, "ORDER BY", str) 145 return qb 146 } 147 148 // Asc join the asc 149 func (qb *PostgresQueryBuilder) Asc() QueryBuilder { 150 qb.tokens = append(qb.tokens, "ASC") 151 return qb 152 } 153 154 // Desc join the desc 155 func (qb *PostgresQueryBuilder) Desc() QueryBuilder { 156 qb.tokens = append(qb.tokens, "DESC") 157 return qb 158 } 159 160 // Limit join the limit num 161 func (qb *PostgresQueryBuilder) Limit(limit int) QueryBuilder { 162 qb.tokens = append(qb.tokens, "LIMIT", strconv.Itoa(limit)) 163 return qb 164 } 165 166 // Offset join the offset num 167 func (qb *PostgresQueryBuilder) Offset(offset int) QueryBuilder { 168 qb.tokens = append(qb.tokens, "OFFSET", strconv.Itoa(offset)) 169 return qb 170 } 171 172 // GroupBy join the Group by fields 173 func (qb *PostgresQueryBuilder) GroupBy(fields ...string) QueryBuilder { 174 str := processingStr(fields) 175 qb.tokens = append(qb.tokens, "GROUP BY", str) 176 return qb 177 } 178 179 // Having join the Having cond 180 func (qb *PostgresQueryBuilder) Having(cond string) QueryBuilder { 181 qb.tokens = append(qb.tokens, "HAVING", cond) 182 return qb 183 } 184 185 // Update join the update table 186 func (qb *PostgresQueryBuilder) Update(tables ...string) QueryBuilder { 187 str := processingStr(tables) 188 qb.tokens = append(qb.tokens, "UPDATE", str) 189 return qb 190 } 191 192 // Set join the set kv 193 func (qb *PostgresQueryBuilder) Set(kv ...string) QueryBuilder { 194 qb.tokens = append(qb.tokens, "SET", strings.Join(kv, CommaSpace)) 195 return qb 196 } 197 198 // Delete join the Delete tables 199 func (qb *PostgresQueryBuilder) Delete(tables ...string) QueryBuilder { 200 qb.tokens = append(qb.tokens, "DELETE") 201 if len(tables) != 0 { 202 str := processingStr(tables) 203 qb.tokens = append(qb.tokens, str) 204 } 205 return qb 206 } 207 208 // InsertInto join the insert SQL 209 func (qb *PostgresQueryBuilder) InsertInto(table string, fields ...string) QueryBuilder { 210 str := fmt.Sprintf("%s%s%s", quote, table, quote) 211 qb.tokens = append(qb.tokens, "INSERT INTO", str) 212 if len(fields) != 0 { 213 fieldsStr := strings.Join(fields, CommaSpace) 214 qb.tokens = append(qb.tokens, "(", fieldsStr, ")") 215 } 216 return qb 217 } 218 219 // Values join the Values(vals) 220 func (qb *PostgresQueryBuilder) Values(vals ...string) QueryBuilder { 221 valsStr := strings.Join(vals, CommaSpace) 222 qb.tokens = append(qb.tokens, "VALUES", "(", valsStr, ")") 223 return qb 224 } 225 226 // Subquery join the sub as alias 227 func (qb *PostgresQueryBuilder) Subquery(sub string, alias string) string { 228 return fmt.Sprintf("(%s) AS %s", sub, alias) 229 } 230 231 // String join all tokens 232 func (qb *PostgresQueryBuilder) String() string { 233 s := strings.Join(qb.tokens, " ") 234 qb.tokens = qb.tokens[:0] 235 return s 236 }