github.com/kotovmak/go-admin@v1.1.1/modules/db/connection.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 "strings" 11 12 "github.com/kotovmak/go-admin/modules/config" 13 "github.com/kotovmak/go-admin/modules/service" 14 ) 15 16 const ( 17 // DriverMysql is a const value of mysql driver. 18 DriverMysql = "mysql" 19 // DriverSqlite is a const value of sqlite driver. 20 DriverSqlite = "sqlite" 21 // DriverPostgresql is a const value of postgresql driver. 22 DriverPostgresql = "postgresql" 23 // DriverMssql is a const value of mssql driver. 24 DriverMssql = "mssql" 25 // DriverOceanBase is a const value of oceanbase driver. 26 DriverOceanBase = "oceanbase" 27 ) 28 29 // Connection is a connection handler of database. 30 type Connection interface { 31 // Query is the query method of sql. 32 Query(query string, args ...interface{}) ([]map[string]interface{}, error) 33 34 // Exec is the exec method of sql. 35 Exec(query string, args ...interface{}) (sql.Result, error) 36 37 // QueryWithConnection is the query method with given connection of sql. 38 QueryWithConnection(conn, query string, args ...interface{}) ([]map[string]interface{}, error) 39 QueryWithTx(tx *sql.Tx, query string, args ...interface{}) ([]map[string]interface{}, error) 40 QueryWith(tx *sql.Tx, conn, query string, args ...interface{}) ([]map[string]interface{}, error) 41 42 // ExecWithConnection is the exec method with given connection of sql. 43 ExecWithConnection(conn, query string, args ...interface{}) (sql.Result, error) 44 ExecWithTx(tx *sql.Tx, query string, args ...interface{}) (sql.Result, error) 45 ExecWith(tx *sql.Tx, conn, query string, args ...interface{}) (sql.Result, error) 46 47 BeginTxWithReadUncommitted() *sql.Tx 48 BeginTxWithReadCommitted() *sql.Tx 49 BeginTxWithRepeatableRead() *sql.Tx 50 BeginTx() *sql.Tx 51 BeginTxWithLevel(level sql.IsolationLevel) *sql.Tx 52 53 BeginTxWithReadUncommittedAndConnection(conn string) *sql.Tx 54 BeginTxWithReadCommittedAndConnection(conn string) *sql.Tx 55 BeginTxWithRepeatableReadAndConnection(conn string) *sql.Tx 56 BeginTxAndConnection(conn string) *sql.Tx 57 BeginTxWithLevelAndConnection(conn string, level sql.IsolationLevel) *sql.Tx 58 59 // InitDB initialize the database connections. 60 InitDB(cfg map[string]config.Database) Connection 61 62 // GetName get the connection name. 63 Name() string 64 65 Close() []error 66 67 GetDelimiter() string 68 GetDelimiter2() string 69 GetDelimiters() []string 70 71 GetDB(key string) *sql.DB 72 73 GetConfig(name string) config.Database 74 75 CreateDB(name string, beans ...interface{}) error 76 } 77 78 // GetConnectionByDriver return the Connection by given driver name. 79 func GetConnectionByDriver(driver string) Connection { 80 switch driver { 81 case "mysql": 82 return GetMysqlDB() 83 case "mssql": 84 return GetMssqlDB() 85 case "sqlite": 86 return GetSqliteDB() 87 case "postgresql": 88 return GetPostgresqlDB() 89 case "oceanbase": 90 return GetOceanBaseDB() 91 default: 92 panic("driver not found!") 93 } 94 } 95 96 func GetConnectionFromService(srv interface{}) Connection { 97 if v, ok := srv.(Connection); ok { 98 return v 99 } 100 panic("wrong service") 101 } 102 103 func GetConnection(srvs service.List) Connection { 104 if v, ok := srvs.Get(config.GetDatabases().GetDefault().Driver).(Connection); ok { 105 return v 106 } 107 panic("wrong service") 108 } 109 110 func GetAggregationExpression(driver, field, headField, delimiter string) string { 111 switch driver { 112 case "postgresql": 113 return fmt.Sprintf("string_agg(%s::character varying, '%s') as %s", field, delimiter, headField) 114 case "mysql": 115 return fmt.Sprintf("group_concat(%s separator '%s') as %s", field, delimiter, headField) 116 case "sqlite": 117 return fmt.Sprintf("group_concat(%s, '%s') as %s", field, delimiter, headField) 118 case "mssql": 119 return fmt.Sprintf("string_agg(%s, '%s') as [%s]", field, delimiter, headField) 120 case "oceanbase": 121 return fmt.Sprintf("group_concat(%s separator '%s') as %s", field, delimiter, headField) 122 123 default: 124 panic("wrong driver") 125 } 126 } 127 128 const ( 129 INSERT = 0 130 DELETE = 1 131 UPDATE = 2 132 QUERY = 3 133 ) 134 135 var ignoreErrors = [...][]string{ 136 // insert 137 { 138 "LastInsertId is not supported", 139 "There is no generated identity value", 140 "LastInsertId is not supported by this driver", 141 }, 142 // delete 143 { 144 "no affect", 145 }, 146 // update 147 { 148 "LastInsertId is not supported", 149 "There is no generated identity value", 150 "no affect", 151 "LastInsertId is not supported by this driver", 152 }, 153 // query 154 { 155 "LastInsertId is not supported", 156 "There is no generated identity value", 157 "no affect", 158 "out of index", 159 "LastInsertId is not supported by this driver", 160 }, 161 } 162 163 func CheckError(err error, t int) bool { 164 if err == nil { 165 return false 166 } 167 for _, msg := range ignoreErrors[t] { 168 if strings.Contains(err.Error(), msg) { 169 return false 170 } 171 } 172 return true 173 }