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  }