github.com/kotovmak/go-admin@v1.1.1/modules/db/postgresql.go (about)

     1  // Copyright 2019 GoAdmin Core Team. All rights reserved.
     2  // Use of this source code is governed by a Apache-2.0 style
     3  // license that can be found in the LICENSE file.
     4  
     5  package db
     6  
     7  import (
     8  	"database/sql"
     9  	"fmt"
    10  	"strconv"
    11  	"strings"
    12  
    13  	"github.com/kotovmak/go-admin/modules/config"
    14  )
    15  
    16  // Postgresql is a Connection of postgresql.
    17  type Postgresql struct {
    18  	Base
    19  }
    20  
    21  // GetPostgresqlDB return the global postgresql connection.
    22  func GetPostgresqlDB() *Postgresql {
    23  	return &Postgresql{
    24  		Base: Base{
    25  			DbList: make(map[string]*sql.DB),
    26  		},
    27  	}
    28  }
    29  
    30  // Name implements the method Connection.Name.
    31  func (db *Postgresql) Name() string {
    32  	return "postgresql"
    33  }
    34  
    35  // GetDelimiter implements the method Connection.GetDelimiter.
    36  func (db *Postgresql) GetDelimiter() string {
    37  	return `"`
    38  }
    39  
    40  // GetDelimiter2 implements the method Connection.GetDelimiter2.
    41  func (db *Postgresql) GetDelimiter2() string {
    42  	return `"`
    43  }
    44  
    45  // GetDelimiters implements the method Connection.GetDelimiters.
    46  func (db *Postgresql) GetDelimiters() []string {
    47  	return []string{`"`, `"`}
    48  }
    49  
    50  // QueryWithConnection implements the method Connection.QueryWithConnection.
    51  func (db *Postgresql) QueryWithConnection(con string, query string, args ...interface{}) ([]map[string]interface{}, error) {
    52  	return CommonQuery(db.DbList[con], filterQuery(query), args...)
    53  }
    54  
    55  // ExecWithConnection implements the method Connection.ExecWithConnection.
    56  func (db *Postgresql) ExecWithConnection(con string, query string, args ...interface{}) (sql.Result, error) {
    57  	return CommonExec(db.DbList[con], filterQuery(query), args...)
    58  }
    59  
    60  // Query implements the method Connection.Query.
    61  func (db *Postgresql) Query(query string, args ...interface{}) ([]map[string]interface{}, error) {
    62  	return CommonQuery(db.DbList["default"], filterQuery(query), args...)
    63  }
    64  
    65  // Exec implements the method Connection.Exec.
    66  func (db *Postgresql) Exec(query string, args ...interface{}) (sql.Result, error) {
    67  	return CommonExec(db.DbList["default"], filterQuery(query), args...)
    68  }
    69  
    70  func (db *Postgresql) QueryWith(tx *sql.Tx, conn, query string, args ...interface{}) ([]map[string]interface{}, error) {
    71  	if tx != nil {
    72  		return db.QueryWithTx(tx, query, args...)
    73  	}
    74  	return db.QueryWithConnection(conn, query, args...)
    75  }
    76  
    77  func (db *Postgresql) ExecWith(tx *sql.Tx, conn, query string, args ...interface{}) (sql.Result, error) {
    78  	if tx != nil {
    79  		return db.ExecWithTx(tx, query, args...)
    80  	}
    81  	return db.ExecWithConnection(conn, query, args...)
    82  }
    83  
    84  func filterQuery(query string) string {
    85  	queCount := strings.Count(query, "?")
    86  	for i := 1; i < queCount+1; i++ {
    87  		query = strings.Replace(query, "?", "$"+strconv.Itoa(i), 1)
    88  	}
    89  	query = strings.ReplaceAll(query, "`", "")
    90  	// TODO: add " to the keyword
    91  	return strings.ReplaceAll(query, "by order ", `by "order" `)
    92  }
    93  
    94  // InitDB implements the method Connection.InitDB.
    95  func (db *Postgresql) InitDB(cfgList map[string]config.Database) Connection {
    96  	db.Configs = cfgList
    97  	db.Once.Do(func() {
    98  		for conn, cfg := range cfgList {
    99  
   100  			fmt.Println("检查 pg 配置", cfg.GetDSN())
   101  
   102  			sqlDB, err := sql.Open("postgres", cfg.GetDSN())
   103  			if err != nil {
   104  				if sqlDB != nil {
   105  					_ = sqlDB.Close()
   106  				}
   107  				panic(err)
   108  			}
   109  
   110  			sqlDB.SetMaxIdleConns(cfg.MaxIdleConns)
   111  			sqlDB.SetMaxOpenConns(cfg.MaxOpenConns)
   112  			sqlDB.SetConnMaxLifetime(cfg.ConnMaxLifetime)
   113  			sqlDB.SetConnMaxIdleTime(cfg.ConnMaxIdleTime)
   114  
   115  			db.DbList[conn] = sqlDB
   116  
   117  			if err := sqlDB.Ping(); err != nil {
   118  				panic(err)
   119  			}
   120  		}
   121  	})
   122  	return db
   123  }
   124  
   125  // BeginTxWithReadUncommitted starts a transaction with level LevelReadUncommitted.
   126  func (db *Postgresql) BeginTxWithReadUncommitted() *sql.Tx {
   127  	return CommonBeginTxWithLevel(db.DbList["default"], sql.LevelReadUncommitted)
   128  }
   129  
   130  // BeginTxWithReadCommitted starts a transaction with level LevelReadCommitted.
   131  func (db *Postgresql) BeginTxWithReadCommitted() *sql.Tx {
   132  	return CommonBeginTxWithLevel(db.DbList["default"], sql.LevelReadCommitted)
   133  }
   134  
   135  // BeginTxWithRepeatableRead starts a transaction with level LevelRepeatableRead.
   136  func (db *Postgresql) BeginTxWithRepeatableRead() *sql.Tx {
   137  	return CommonBeginTxWithLevel(db.DbList["default"], sql.LevelRepeatableRead)
   138  }
   139  
   140  // BeginTx starts a transaction with level LevelDefault.
   141  func (db *Postgresql) BeginTx() *sql.Tx {
   142  	return CommonBeginTxWithLevel(db.DbList["default"], sql.LevelDefault)
   143  }
   144  
   145  // BeginTxWithLevel starts a transaction with given transaction isolation level.
   146  func (db *Postgresql) BeginTxWithLevel(level sql.IsolationLevel) *sql.Tx {
   147  	return CommonBeginTxWithLevel(db.DbList["default"], level)
   148  }
   149  
   150  // BeginTxWithReadUncommittedAndConnection starts a transaction with level LevelReadUncommitted and connection.
   151  func (db *Postgresql) BeginTxWithReadUncommittedAndConnection(conn string) *sql.Tx {
   152  	return CommonBeginTxWithLevel(db.DbList[conn], sql.LevelReadUncommitted)
   153  }
   154  
   155  // BeginTxWithReadCommittedAndConnection starts a transaction with level LevelReadCommitted and connection.
   156  func (db *Postgresql) BeginTxWithReadCommittedAndConnection(conn string) *sql.Tx {
   157  	return CommonBeginTxWithLevel(db.DbList[conn], sql.LevelReadCommitted)
   158  }
   159  
   160  // BeginTxWithRepeatableReadAndConnection starts a transaction with level LevelRepeatableRead and connection.
   161  func (db *Postgresql) BeginTxWithRepeatableReadAndConnection(conn string) *sql.Tx {
   162  	return CommonBeginTxWithLevel(db.DbList[conn], sql.LevelRepeatableRead)
   163  }
   164  
   165  // BeginTxAndConnection starts a transaction with level LevelDefault and connection.
   166  func (db *Postgresql) BeginTxAndConnection(conn string) *sql.Tx {
   167  	return CommonBeginTxWithLevel(db.DbList[conn], sql.LevelDefault)
   168  }
   169  
   170  // BeginTxWithLevelAndConnection starts a transaction with given transaction isolation level and connection.
   171  func (db *Postgresql) BeginTxWithLevelAndConnection(conn string, level sql.IsolationLevel) *sql.Tx {
   172  	return CommonBeginTxWithLevel(db.DbList[conn], level)
   173  }
   174  
   175  // QueryWithTx is query method within the transaction.
   176  func (db *Postgresql) QueryWithTx(tx *sql.Tx, query string, args ...interface{}) ([]map[string]interface{}, error) {
   177  	return CommonQueryWithTx(tx, filterQuery(query), args...)
   178  }
   179  
   180  // ExecWithTx is exec method within the transaction.
   181  func (db *Postgresql) ExecWithTx(tx *sql.Tx, query string, args ...interface{}) (sql.Result, error) {
   182  	return CommonExecWithTx(tx, filterQuery(query), args...)
   183  }