Этот коммит содержится в:
Ibrahim Serdar Acikgoz
2022-01-08 11:16:07 +03:00
коммит произвёл GitHub
родитель c8198fbefe
Коммит 6595b31f23
406 изменённых файлов: 16617 добавлений и 6957 удалений

Просмотреть файл

@@ -8,7 +8,6 @@ import (
"database/sql"
dbsql "database/sql"
"fmt"
"os"
"path/filepath"
"strconv"
"strings"
@@ -17,13 +16,15 @@ import (
"time"
sq "github.com/Masterminds/squirrel"
"github.com/go-morph/morph"
"github.com/go-morph/morph/drivers"
ms "github.com/go-morph/morph/drivers/mysql"
ps "github.com/go-morph/morph/drivers/postgres"
mbindata "github.com/go-morph/morph/sources/go_bindata"
"github.com/go-sql-driver/mysql"
"github.com/golang-migrate/migrate/v4"
"github.com/golang-migrate/migrate/v4/database"
mysqlmigrate "github.com/golang-migrate/migrate/v4/database/mysql"
"github.com/golang-migrate/migrate/v4/database/postgres"
_ "github.com/golang-migrate/migrate/v4/source/file"
bindata "github.com/golang-migrate/migrate/v4/source/go_bindata"
"github.com/jmoiron/sqlx"
"github.com/lib/pq"
_ "github.com/lib/pq"
@@ -215,38 +216,10 @@ func New(settings model.SqlSettings, metrics einterfaces.MetricsInterface) *SqlS
mlog.Fatal("Failed to upgrade database.", mlog.Err(err))
}
store.stores.channel.(*SqlChannelStore).createIndexesIfNotExists()
store.stores.post.(*SqlPostStore).createIndexesIfNotExists()
store.stores.retentionPolicy.(*SqlRetentionPolicyStore).createIndexesIfNotExists()
store.stores.thread.(*SqlThreadStore).createIndexesIfNotExists()
store.stores.user.(*SqlUserStore).createIndexesIfNotExists()
store.stores.bot.(*SqlBotStore).createIndexesIfNotExists()
store.stores.audit.(*SqlAuditStore).createIndexesIfNotExists()
store.stores.compliance.(*SqlComplianceStore).createIndexesIfNotExists()
store.stores.session.(*SqlSessionStore).createIndexesIfNotExists()
store.stores.oauth.(*SqlOAuthStore).createIndexesIfNotExists()
store.stores.system.(*SqlSystemStore).createIndexesIfNotExists()
store.stores.webhook.(*SqlWebhookStore).createIndexesIfNotExists()
store.stores.command.(*SqlCommandStore).createIndexesIfNotExists()
store.stores.commandWebhook.(*SqlCommandWebhookStore).createIndexesIfNotExists()
store.stores.preference.(*SqlPreferenceStore).createIndexesIfNotExists()
store.stores.license.(*SqlLicenseStore).createIndexesIfNotExists()
store.stores.token.(*SqlTokenStore).createIndexesIfNotExists()
store.stores.emoji.(*SqlEmojiStore).createIndexesIfNotExists()
store.stores.status.(*SqlStatusStore).createIndexesIfNotExists()
store.stores.fileInfo.(*SqlFileInfoStore).createIndexesIfNotExists()
store.stores.uploadSession.(*SqlUploadSessionStore).createIndexesIfNotExists()
store.stores.job.(*SqlJobStore).createIndexesIfNotExists()
store.stores.userAccessToken.(*SqlUserAccessTokenStore).createIndexesIfNotExists()
store.stores.plugin.(*SqlPluginStore).createIndexesIfNotExists()
store.stores.TermsOfService.(SqlTermsOfServiceStore).createIndexesIfNotExists()
store.stores.productNotices.(SqlProductNoticesStore).createIndexesIfNotExists()
store.stores.UserTermsOfService.(SqlUserTermsOfServiceStore).createIndexesIfNotExists()
store.stores.linkMetadata.(*SqlLinkMetadataStore).createIndexesIfNotExists()
store.stores.sharedchannel.(*SqlSharedChannelStore).createIndexesIfNotExists()
store.stores.group.(*SqlGroupStore).createIndexesIfNotExists()
store.stores.scheme.(*SqlSchemeStore).createIndexesIfNotExists()
store.stores.remoteCluster.(*sqlRemoteClusterStore).createIndexesIfNotExists()
store.stores.preference.(*SqlPreferenceStore).deleteUnusedFeatures()
return store
@@ -673,6 +646,27 @@ func (ss *SqlStore) DoesColumnExist(tableName string, columnName string) bool {
}
}
func (ss *SqlStore) DoesIndexExist(indexName string, tableName string) bool {
if ss.DriverName() == model.DatabaseDriverPostgres {
_, err := ss.GetMaster().SelectStr("SELECT $1::regclass", indexName)
// It should fail if the index does not exist
return err == nil
} else if ss.DriverName() == model.DatabaseDriverMysql {
count, err := ss.GetMaster().SelectInt("SELECT COUNT(0) AS index_exists FROM information_schema.statistics WHERE TABLE_SCHEMA = DATABASE() and table_name = ? AND index_name = ?", tableName, indexName)
if err != nil {
mlog.Fatal("Failed to check index", mlog.Err(err))
}
if count <= 0 {
return false
}
} else {
mlog.Fatal("Failed to check if index exists because of missing driver")
}
return true
}
// GetColumnInfo returns data type information about the given column.
func (ss *SqlStore) GetColumnInfo(tableName, columnName string) (*ColumnInfo, error) {
var columnInfo ColumnInfo
@@ -1426,32 +1420,8 @@ func (ss *SqlStore) GetLicense() *model.License {
}
func (ss *SqlStore) migrate(direction migrationDirection) error {
var driver database.Driver
var err error
// golang-migrate doesn't have a way to reuse an existing connection in a migration.
// The current API will always close the current connection _as well as_ the *sql.DB
// instance along with it. Which means that we cannot pass an existing DB instance,
// because it will be closed. Therefore, we always have to create a new instance,
// and therefore a new connection.
dataSource, err := ss.appendMultipleStatementsFlag(*ss.settings.DataSource)
if err != nil {
return err
}
db := setupConnection("migrations", dataSource, ss.settings)
defer db.Close()
if ss.DriverName() == model.DatabaseDriverMysql {
driver, err = mysqlmigrate.WithInstance(db, &mysqlmigrate.Config{})
if err != nil {
return err
}
} else {
driver, err = postgres.WithInstance(db, &postgres.Config{})
if err != nil {
return err
}
}
// we need to compute missing migrations (if any) and manually save unnecessary migrations
// to the db_migrations table. So that previous migrations won't get applied
var assetNamesForDriver []string
for _, assetName := range migrations.AssetNames() {
@@ -1460,39 +1430,53 @@ func (ss *SqlStore) migrate(direction migrationDirection) error {
}
}
source := bindata.Resource(assetNamesForDriver, func(name string) ([]byte, error) {
return migrations.Asset(filepath.Join(ss.DriverName(), name))
src, err := mbindata.WithInstance(&mbindata.AssetSource{
Names: assetNamesForDriver,
AssetFunc: func(name string) ([]byte, error) {
return migrations.Asset(filepath.Join(ss.DriverName(), name))
},
})
if err != nil {
return err
}
defer src.Close()
sourceDriver, err := bindata.WithInstance(source)
var driver drivers.Driver
switch ss.DriverName() {
case model.DatabaseDriverMysql:
dataSource, err2 := ss.appendMultipleStatementsFlag(*ss.settings.DataSource)
if err2 != nil {
return err2
}
db := setupConnection("master", dataSource, ss.settings)
driver, err = ms.WithInstance(db, &ms.Config{
StatementTimeoutInSecs: *ss.settings.MigrationsStatementTimeoutSeconds,
})
defer db.Close()
case model.DatabaseDriverPostgres:
driver, err = ps.WithInstance(ss.GetMasterX().DB.DB, &ps.Config{
StatementTimeoutInSecs: *ss.settings.MigrationsStatementTimeoutSeconds,
})
default:
err = fmt.Errorf("unsupported database type %s for migration", ss.DriverName())
}
if err != nil {
return err
}
migrations, err := migrate.NewWithInstance("go-bindata",
sourceDriver,
ss.DriverName(),
driver)
engine, err := morph.New(driver, src)
if err != nil {
return err
}
defer migrations.Close()
defer engine.Close()
switch direction {
case migrationsDirectionUp:
err = migrations.Up()
case migrationsDirectionDown:
err = migrations.Down()
default:
return errors.New(fmt.Sprintf("unsupported migration direction %s", direction))
}
if err != nil && err != migrate.ErrNoChange && !errors.Is(err, os.ErrNotExist) {
_, err = engine.ApplyDown(-1)
return err
default:
return engine.ApplyAll()
}
return nil
}
func (ss *SqlStore) appendMultipleStatementsFlag(dataSource string) (string, error) {