Prepare support for sqlx (#18133)
* Prepare support for sqlx Just setting up some basic skeleton to start replacing gorp queries with sqlx. There is still an issue with efficiently writing cross-platform named queries, because :FieldName needs to be :fieldname for Postgres. The positional params can be rebound depending on driver name. But named queries can't from my investigation. Will look into this. ```release-note NONE ``` * Refactor mapper ```release-note NONE ``` * Forgot to init slice ```release-note NONE ``` Co-authored-by: Mattermod <mattermod@users.noreply.github.com>
Этот коммит содержится в:
коммит произвёл
GitHub
родитель
d5160ab59d
Коммит
b553b50e15
@@ -23,6 +23,7 @@ import (
|
|||||||
"github.com/golang-migrate/migrate/v4/database/postgres"
|
"github.com/golang-migrate/migrate/v4/database/postgres"
|
||||||
_ "github.com/golang-migrate/migrate/v4/source/file"
|
_ "github.com/golang-migrate/migrate/v4/source/file"
|
||||||
bindata "github.com/golang-migrate/migrate/v4/source/go_bindata"
|
bindata "github.com/golang-migrate/migrate/v4/source/go_bindata"
|
||||||
|
"github.com/jmoiron/sqlx"
|
||||||
"github.com/lib/pq"
|
"github.com/lib/pq"
|
||||||
_ "github.com/lib/pq"
|
_ "github.com/lib/pq"
|
||||||
"github.com/mattermost/gorp"
|
"github.com/mattermost/gorp"
|
||||||
@@ -137,11 +138,18 @@ type SqlStoreStores struct {
|
|||||||
type SqlStore struct {
|
type SqlStore struct {
|
||||||
// rrCounter and srCounter should be kept first.
|
// rrCounter and srCounter should be kept first.
|
||||||
// See https://github.com/mattermost/mattermost-server/v6/pull/7281
|
// See https://github.com/mattermost/mattermost-server/v6/pull/7281
|
||||||
rrCounter int64
|
rrCounter int64
|
||||||
srCounter int64
|
srCounter int64
|
||||||
master *gorp.DbMap
|
|
||||||
Replicas []*gorp.DbMap
|
master *gorp.DbMap
|
||||||
searchReplicas []*gorp.DbMap
|
masterX *sqlx.DB
|
||||||
|
|
||||||
|
Replicas []*gorp.DbMap
|
||||||
|
ReplicaXs []*sqlx.DB
|
||||||
|
|
||||||
|
searchReplicas []*gorp.DbMap
|
||||||
|
searchReplicaXs []*sqlx.DB
|
||||||
|
|
||||||
replicaLagHandles []*dbsql.DB
|
replicaLagHandles []*dbsql.DB
|
||||||
stores SqlStoreStores
|
stores SqlStoreStores
|
||||||
settings *model.SqlSettings
|
settings *model.SqlSettings
|
||||||
@@ -278,7 +286,7 @@ func New(settings model.SqlSettings, metrics einterfaces.MetricsInterface) *SqlS
|
|||||||
return store
|
return store
|
||||||
}
|
}
|
||||||
|
|
||||||
func setupConnection(connType string, dataSource string, settings *model.SqlSettings) *gorp.DbMap {
|
func setupConnection(connType string, dataSource string, settings *model.SqlSettings) *dbsql.DB {
|
||||||
db, err := dbsql.Open(*settings.DriverName, dataSource)
|
db, err := dbsql.Open(*settings.DriverName, dataSource)
|
||||||
if err != nil {
|
if err != nil {
|
||||||
mlog.Critical("Failed to open SQL connection to err.", mlog.Err(err))
|
mlog.Critical("Failed to open SQL connection to err.", mlog.Err(err))
|
||||||
@@ -322,9 +330,7 @@ func setupConnection(connType string, dataSource string, settings *model.SqlSett
|
|||||||
db.SetConnMaxLifetime(time.Duration(*settings.ConnMaxLifetimeMilliseconds) * time.Millisecond)
|
db.SetConnMaxLifetime(time.Duration(*settings.ConnMaxLifetimeMilliseconds) * time.Millisecond)
|
||||||
db.SetConnMaxIdleTime(time.Duration(*settings.ConnMaxIdleTimeMilliseconds) * time.Millisecond)
|
db.SetConnMaxIdleTime(time.Duration(*settings.ConnMaxIdleTimeMilliseconds) * time.Millisecond)
|
||||||
|
|
||||||
dbMap := getDBMap(settings, db)
|
return db
|
||||||
|
|
||||||
return dbMap
|
|
||||||
}
|
}
|
||||||
|
|
||||||
func getDBMap(settings *model.SqlSettings, db *dbsql.DB) *gorp.DbMap {
|
func getDBMap(settings *model.SqlSettings, db *dbsql.DB) *gorp.DbMap {
|
||||||
@@ -365,6 +371,8 @@ func (ss *SqlStore) Context() context.Context {
|
|||||||
return ss.context
|
return ss.context
|
||||||
}
|
}
|
||||||
|
|
||||||
|
func noOpMapper(s string) string { return s }
|
||||||
|
|
||||||
func (ss *SqlStore) initConnection() {
|
func (ss *SqlStore) initConnection() {
|
||||||
dataSource := *ss.settings.DataSource
|
dataSource := *ss.settings.DataSource
|
||||||
if ss.DriverName() == model.DatabaseDriverMysql {
|
if ss.DriverName() == model.DatabaseDriverMysql {
|
||||||
@@ -379,19 +387,36 @@ func (ss *SqlStore) initConnection() {
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
ss.master = setupConnection("master", dataSource, ss.settings)
|
handle := setupConnection("master", dataSource, ss.settings)
|
||||||
|
ss.master = getDBMap(ss.settings, handle)
|
||||||
|
ss.masterX = sqlx.NewDb(handle, ss.DriverName())
|
||||||
|
if ss.DriverName() == model.DatabaseDriverMysql {
|
||||||
|
ss.masterX.MapperFunc(noOpMapper)
|
||||||
|
}
|
||||||
|
|
||||||
if len(ss.settings.DataSourceReplicas) > 0 {
|
if len(ss.settings.DataSourceReplicas) > 0 {
|
||||||
ss.Replicas = make([]*gorp.DbMap, len(ss.settings.DataSourceReplicas))
|
ss.Replicas = make([]*gorp.DbMap, len(ss.settings.DataSourceReplicas))
|
||||||
|
ss.ReplicaXs = make([]*sqlx.DB, len(ss.settings.DataSourceReplicas))
|
||||||
for i, replica := range ss.settings.DataSourceReplicas {
|
for i, replica := range ss.settings.DataSourceReplicas {
|
||||||
ss.Replicas[i] = setupConnection(fmt.Sprintf("replica-%v", i), replica, ss.settings)
|
handle := setupConnection(fmt.Sprintf("replica-%v", i), replica, ss.settings)
|
||||||
|
ss.Replicas[i] = getDBMap(ss.settings, handle)
|
||||||
|
ss.ReplicaXs[i] = sqlx.NewDb(handle, ss.DriverName())
|
||||||
|
if ss.DriverName() == model.DatabaseDriverMysql {
|
||||||
|
ss.ReplicaXs[i].MapperFunc(noOpMapper)
|
||||||
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
if len(ss.settings.DataSourceSearchReplicas) > 0 {
|
if len(ss.settings.DataSourceSearchReplicas) > 0 {
|
||||||
ss.searchReplicas = make([]*gorp.DbMap, len(ss.settings.DataSourceSearchReplicas))
|
ss.searchReplicas = make([]*gorp.DbMap, len(ss.settings.DataSourceSearchReplicas))
|
||||||
|
ss.searchReplicaXs = make([]*sqlx.DB, len(ss.settings.DataSourceSearchReplicas))
|
||||||
for i, replica := range ss.settings.DataSourceSearchReplicas {
|
for i, replica := range ss.settings.DataSourceSearchReplicas {
|
||||||
ss.searchReplicas[i] = setupConnection(fmt.Sprintf("search-replica-%v", i), replica, ss.settings)
|
handle := setupConnection(fmt.Sprintf("search-replica-%v", i), replica, ss.settings)
|
||||||
|
ss.searchReplicas[i] = getDBMap(ss.settings, handle)
|
||||||
|
ss.searchReplicaXs[i] = sqlx.NewDb(handle, ss.DriverName())
|
||||||
|
if ss.DriverName() == model.DatabaseDriverMysql {
|
||||||
|
ss.searchReplicaXs[i].MapperFunc(noOpMapper)
|
||||||
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
@@ -401,8 +426,7 @@ func (ss *SqlStore) initConnection() {
|
|||||||
if src.DataSource == nil {
|
if src.DataSource == nil {
|
||||||
continue
|
continue
|
||||||
}
|
}
|
||||||
gorpConn := setupConnection(fmt.Sprintf(replicaLagPrefix+"-%d", i), *src.DataSource, ss.settings)
|
ss.replicaLagHandles[i] = setupConnection(fmt.Sprintf(replicaLagPrefix+"-%d", i), *src.DataSource, ss.settings)
|
||||||
ss.replicaLagHandles[i] = gorpConn.Db
|
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
@@ -446,6 +470,10 @@ func (ss *SqlStore) GetMaster() *gorp.DbMap {
|
|||||||
return ss.master
|
return ss.master
|
||||||
}
|
}
|
||||||
|
|
||||||
|
func (ss *SqlStore) GetMasterX() *sqlx.DB {
|
||||||
|
return ss.masterX
|
||||||
|
}
|
||||||
|
|
||||||
func (ss *SqlStore) GetSearchReplica() *gorp.DbMap {
|
func (ss *SqlStore) GetSearchReplica() *gorp.DbMap {
|
||||||
ss.licenseMutex.RLock()
|
ss.licenseMutex.RLock()
|
||||||
license := ss.license
|
license := ss.license
|
||||||
@@ -474,6 +502,18 @@ func (ss *SqlStore) GetReplica() *gorp.DbMap {
|
|||||||
return ss.Replicas[rrNum]
|
return ss.Replicas[rrNum]
|
||||||
}
|
}
|
||||||
|
|
||||||
|
func (ss *SqlStore) GetReplicaX() *sqlx.DB {
|
||||||
|
ss.licenseMutex.RLock()
|
||||||
|
license := ss.license
|
||||||
|
ss.licenseMutex.RUnlock()
|
||||||
|
if len(ss.settings.DataSourceReplicas) == 0 || ss.lockedToMaster || license == nil {
|
||||||
|
return ss.GetMasterX()
|
||||||
|
}
|
||||||
|
|
||||||
|
rrNum := atomic.AddInt64(&ss.rrCounter, 1) % int64(len(ss.Replicas))
|
||||||
|
return ss.ReplicaXs[rrNum]
|
||||||
|
}
|
||||||
|
|
||||||
func (ss *SqlStore) TotalMasterDbConnections() int {
|
func (ss *SqlStore) TotalMasterDbConnections() int {
|
||||||
return ss.GetMaster().Db.Stats().OpenConnections
|
return ss.GetMaster().Db.Stats().OpenConnections
|
||||||
}
|
}
|
||||||
@@ -1468,16 +1508,16 @@ func (ss *SqlStore) migrate(direction migrationDirection) error {
|
|||||||
if err != nil {
|
if err != nil {
|
||||||
return err
|
return err
|
||||||
}
|
}
|
||||||
conn := setupConnection("migrations", dataSource, ss.settings)
|
db := setupConnection("migrations", dataSource, ss.settings)
|
||||||
defer conn.Db.Close()
|
defer db.Close()
|
||||||
|
|
||||||
if ss.DriverName() == model.DatabaseDriverMysql {
|
if ss.DriverName() == model.DatabaseDriverMysql {
|
||||||
driver, err = mysqlmigrate.WithInstance(conn.Db, &mysqlmigrate.Config{})
|
driver, err = mysqlmigrate.WithInstance(db, &mysqlmigrate.Config{})
|
||||||
if err != nil {
|
if err != nil {
|
||||||
return err
|
return err
|
||||||
}
|
}
|
||||||
} else {
|
} else {
|
||||||
driver, err = postgres.WithInstance(conn.Db, &postgres.Config{})
|
driver, err = postgres.WithInstance(db, &postgres.Config{})
|
||||||
if err != nil {
|
if err != nil {
|
||||||
return err
|
return err
|
||||||
}
|
}
|
||||||
|
|||||||
Ссылка в новой задаче
Block a user