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 }