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

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

@@ -31,10 +31,6 @@ func newSqlAuditStore(sqlStore *SqlStore) store.AuditStore {
return s
}
func (s SqlAuditStore) createIndexesIfNotExists() {
s.CreateIndexIfNotExists("idx_audits_user_id", "Audits", "UserId")
}
func (s SqlAuditStore) Save(audit *model.Audit) error {
audit.Id = model.NewId()
audit.CreateAt = model.GetMillis()

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

@@ -63,9 +63,6 @@ func newSqlBotStore(sqlStore *SqlStore, metrics einterfaces.MetricsInterface) st
return us
}
func (us SqlBotStore) createIndexesIfNotExists() {
}
// Get fetches the given bot in the database.
func (us SqlBotStore) Get(botUserId string, includeDeleted bool) (*model.Bot, error) {
var excludeDeletedSql = "AND b.DeleteAt = 0"

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

@@ -506,55 +506,6 @@ func newSqlChannelStore(sqlStore *SqlStore, metrics einterfaces.MetricsInterface
return s
}
func (s SqlChannelStore) createIndexesIfNotExists() {
s.CreateIndexIfNotExists("idx_channels_update_at", "Channels", "UpdateAt")
s.CreateIndexIfNotExists("idx_channels_create_at", "Channels", "CreateAt")
s.CreateIndexIfNotExists("idx_channels_delete_at", "Channels", "DeleteAt")
s.CreateIndexIfNotExists("idx_channels_scheme_id", "Channels", "SchemeId")
s.CreateCompositeIndexIfNotExists("idx_channels_team_id_display_name", "Channels", []string{"TeamId", "DisplayName"})
s.CreateCompositeIndexIfNotExists("idx_channels_team_id_type", "Channels", []string{"TeamId", "Type"})
if s.DriverName() == model.DatabaseDriverPostgres {
s.CreateIndexIfNotExists("idx_channels_name_lower", "Channels", "lower(Name)")
s.CreateIndexIfNotExists("idx_channels_displayname_lower", "Channels", "lower(DisplayName)")
}
s.CreateCompositeIndexIfNotExists("idx_channelmembers_user_id_channel_id_last_viewed_at", "ChannelMembers", []string{"UserId", "ChannelId", "LastViewedAt"})
s.CreateCompositeIndexIfNotExists("idx_channelmembers_channel_id_scheme_guest_user_id", "ChannelMembers", []string{"ChannelId", "SchemeGuest", "UserId"})
s.CreateFullTextIndexIfNotExists("idx_channel_search_txt", "Channels", "Name, DisplayName, Purpose")
s.CreateIndexIfNotExists("idx_publicchannels_team_id", "PublicChannels", "TeamId")
s.CreateIndexIfNotExists("idx_publicchannels_delete_at", "PublicChannels", "DeleteAt")
if s.DriverName() == model.DatabaseDriverPostgres {
s.CreateIndexIfNotExists("idx_publicchannels_name_lower", "PublicChannels", "lower(Name)")
s.CreateIndexIfNotExists("idx_publicchannels_displayname_lower", "PublicChannels", "lower(DisplayName)")
}
s.CreateFullTextIndexIfNotExists("idx_publicchannels_search_txt", "PublicChannels", "Name, DisplayName, Purpose")
}
// MigratePublicChannels initializes the PublicChannels table with data created before this version
// of the Mattermost server kept it up-to-date.
func (s SqlChannelStore) MigratePublicChannels() error {
if _, err := s.GetMaster().Exec(`
INSERT INTO PublicChannels
(Id, DeleteAt, TeamId, DisplayName, Name, Header, Purpose)
SELECT
c.Id, c.DeleteAt, c.TeamId, c.DisplayName, c.Name, c.Header, c.Purpose
FROM
Channels c
LEFT JOIN
PublicChannels pc ON (pc.Id = c.Id)
WHERE
c.Type = 'O'
AND pc.Id IS NULL
`); err != nil {
return err
}
return nil
}
func (s SqlChannelStore) upsertPublicChannelT(transaction *gorp.Transaction, channel *model.Channel) error {
publicChannel := &publicChannel{
Id: channel.Id,

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

@@ -47,13 +47,6 @@ func newSqlCommandStore(sqlStore *SqlStore) store.CommandStore {
return s
}
func (s SqlCommandStore) createIndexesIfNotExists() {
s.CreateIndexIfNotExists("idx_command_team_id", "Commands", "TeamId")
s.CreateIndexIfNotExists("idx_command_update_at", "Commands", "UpdateAt")
s.CreateIndexIfNotExists("idx_command_create_at", "Commands", "CreateAt")
s.CreateIndexIfNotExists("idx_command_delete_at", "Commands", "DeleteAt")
}
func (s SqlCommandStore) Save(command *model.Command) (*model.Command, error) {
if command.Id != "" {
return nil, store.NewErrInvalidInput("Command", "CommandId", command.Id)

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

@@ -33,10 +33,6 @@ func newSqlCommandWebhookStore(sqlStore *SqlStore) store.CommandWebhookStore {
return s
}
func (s SqlCommandWebhookStore) createIndexesIfNotExists() {
s.CreateIndexIfNotExists("idx_command_webhook_create_at", "CommandWebhooks", "CreateAt")
}
func (s SqlCommandWebhookStore) Save(webhook *model.CommandWebhook) (*model.CommandWebhook, error) {
if webhook.Id != "" {
return nil, store.NewErrInvalidInput("CommandWebhook", "id", webhook.Id)

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

@@ -36,9 +36,6 @@ func newSqlComplianceStore(sqlStore *SqlStore) store.ComplianceStore {
return s
}
func (s SqlComplianceStore) createIndexesIfNotExists() {
}
func (s SqlComplianceStore) Save(compliance *model.Compliance) (*model.Compliance, error) {
compliance.PreSave()
if err := compliance.IsValid(); err != nil {

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

@@ -122,19 +122,6 @@ func newSqlFileInfoStore(sqlStore *SqlStore, metrics einterfaces.MetricsInterfac
return s
}
func (fs SqlFileInfoStore) createIndexesIfNotExists() {
fs.CreateIndexIfNotExists("idx_fileinfo_update_at", "FileInfo", "UpdateAt")
fs.CreateIndexIfNotExists("idx_fileinfo_create_at", "FileInfo", "CreateAt")
fs.CreateIndexIfNotExists("idx_fileinfo_delete_at", "FileInfo", "DeleteAt")
fs.CreateIndexIfNotExists("idx_fileinfo_postid_at", "FileInfo", "PostId")
fs.CreateIndexIfNotExists("idx_fileinfo_extension_at", "FileInfo", "Extension")
fs.CreateFullTextIndexIfNotExists("idx_fileinfo_name_txt", "FileInfo", "Name")
if fs.DriverName() == model.DatabaseDriverPostgres {
fs.CreateFullTextFuncIndexIfNotExists("idx_fileinfo_name_splitted", "FileInfo", "Translate(Name, '.,-', ' ')")
}
fs.CreateFullTextIndexIfNotExists("idx_fileinfo_content_txt", "FileInfo", "Content")
}
func (fs SqlFileInfoStore) Save(info *model.FileInfo) (*model.FileInfo, error) {
info.PreSave()
if err := info.IsValid(); err != nil {

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

@@ -61,7 +61,6 @@ func newSqlGroupStore(sqlStore *SqlStore) store.GroupStore {
groups.ColMap("Description").SetMaxSize(model.GroupDescriptionMaxLength)
groups.ColMap("Source").SetMaxSize(model.GroupSourceMaxLength)
groups.ColMap("RemoteId").SetMaxSize(model.GroupRemoteIDMaxLength)
groups.SetUniqueTogether("Source", "RemoteId")
groupMembers := db.AddTableWithName(model.GroupMember{}, "GroupMembers").SetKeys(false, "GroupId", "UserId")
groupMembers.ColMap("GroupId").SetMaxSize(26)
@@ -79,15 +78,8 @@ func newSqlGroupStore(sqlStore *SqlStore) store.GroupStore {
}
func (s *SqlGroupStore) createIndexesIfNotExists() {
s.CreateIndexIfNotExists("idx_groupmembers_create_at", "GroupMembers", "CreateAt")
s.CreateIndexIfNotExists("idx_usergroups_remote_id", "UserGroups", "RemoteId")
s.CreateIndexIfNotExists("idx_usergroups_delete_at", "UserGroups", "DeleteAt")
s.CreateIndexIfNotExists("idx_groupteams_teamid", "GroupTeams", "TeamId")
s.CreateIndexIfNotExists("idx_groupchannels_channelid", "GroupChannels", "ChannelId")
s.CreateColumnIfNotExistsNoDefault("Channels", "GroupConstrained", "tinyint(1)", "boolean")
s.CreateColumnIfNotExistsNoDefault("Teams", "GroupConstrained", "tinyint(1)", "boolean")
s.CreateIndexIfNotExists("idx_groupteams_schemeadmin", "GroupTeams", "SchemeAdmin")
s.CreateIndexIfNotExists("idx_groupchannels_schemeadmin", "GroupChannels", "SchemeAdmin")
}
func (s *SqlGroupStore) Create(group *model.Group) (*model.Group, error) {

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

@@ -39,11 +39,6 @@ func newSqlJobStore(sqlStore *SqlStore) store.JobStore {
return s
}
func (jss SqlJobStore) createIndexesIfNotExists() {
jss.CreateIndexIfNotExists("idx_jobs_type", "Jobs", "Type")
jss.CreateCompositeIndexIfNotExists("idx_jobs_status_type", "Jobs", []string{"Status", "Type"})
}
func (jss SqlJobStore) Save(job *model.Job) (*model.Job, error) {
jsonData, err := json.Marshal(job.Data)
if err != nil {

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

@@ -29,9 +29,6 @@ func newSqlLicenseStore(sqlStore *SqlStore) store.LicenseStore {
return ls
}
func (ls SqlLicenseStore) createIndexesIfNotExists() {
}
// Save validates and stores the license instance in the database. The Id
// and Bytes fields are mandatory. The Bytes field is limited to a maximum
// of 10000 bytes. If the license ID matches an existing license in the

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

@@ -31,14 +31,6 @@ func newSqlLinkMetadataStore(sqlStore *SqlStore) store.LinkMetadataStore {
return s
}
func (s SqlLinkMetadataStore) createIndexesIfNotExists() {
if s.DriverName() == model.DatabaseDriverMysql {
s.CreateCompositeIndexIfNotExists("idx_link_metadata_url_timestamp", "LinkMetadata", []string{"URL(512)", "Timestamp"})
} else {
s.CreateCompositeIndexIfNotExists("idx_link_metadata_url_timestamp", "LinkMetadata", []string{"URL", "Timestamp"})
}
}
func (s SqlLinkMetadataStore) Save(metadata *model.LinkMetadata) (*model.LinkMetadata, error) {
if err := metadata.IsValid(); err != nil {
return nil, err

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

@@ -52,12 +52,6 @@ func newSqlOAuthStore(sqlStore *SqlStore) store.OAuthStore {
return as
}
func (as SqlOAuthStore) createIndexesIfNotExists() {
as.CreateIndexIfNotExists("idx_oauthapps_creator_id", "OAuthApps", "CreatorId")
as.CreateIndexIfNotExists("idx_oauthaccessdata_user_id", "OAuthAccessData", "UserId")
as.CreateIndexIfNotExists("idx_oauthaccessdata_refresh_token", "OAuthAccessData", "RefreshToken")
}
func (as SqlOAuthStore) SaveApp(app *model.OAuthApp) (*model.OAuthApp, error) {
if app.Id != "" {
return nil, store.NewErrInvalidInput("OAuthApp", "Id", app.Id)

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

@@ -36,9 +36,6 @@ func newSqlPluginStore(sqlStore *SqlStore) store.PluginStore {
return s
}
func (ps SqlPluginStore) createIndexesIfNotExists() {
}
func (ps SqlPluginStore) SaveOrUpdate(kv *model.PluginKeyValue) (*model.PluginKeyValue, error) {
if err := kv.IsValid(); err != nil {
return nil, err

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

@@ -220,21 +220,6 @@ func newSqlPostStore(sqlStore *SqlStore, metrics einterfaces.MetricsInterface) s
return s
}
func (s *SqlPostStore) createIndexesIfNotExists() {
s.CreateIndexIfNotExists("idx_posts_update_at", "Posts", "UpdateAt")
s.CreateIndexIfNotExists("idx_posts_create_at", "Posts", "CreateAt")
s.CreateIndexIfNotExists("idx_posts_delete_at", "Posts", "DeleteAt")
s.CreateIndexIfNotExists("idx_posts_user_id", "Posts", "UserId")
s.CreateIndexIfNotExists("idx_posts_is_pinned", "Posts", "IsPinned")
s.CreateCompositeIndexIfNotExists("idx_posts_channel_id_update_at", "Posts", []string{"ChannelId", "UpdateAt"})
s.CreateCompositeIndexIfNotExists("idx_posts_channel_id_delete_at_create_at", "Posts", []string{"ChannelId", "DeleteAt", "CreateAt"})
s.CreateCompositeIndexIfNotExists("idx_posts_root_id_delete_at", "Posts", []string{"RootId", "DeleteAt"})
s.CreateFullTextIndexIfNotExists("idx_posts_message_txt", "Posts", "Message")
s.CreateFullTextIndexIfNotExists("idx_posts_hashtags_txt", "Posts", "Hashtags")
}
func (s *SqlPostStore) SaveMultiple(posts []*model.Post) ([]*model.Post, int, error) {
channelNewPosts := make(map[string]int)
channelNewRootPosts := make(map[string]int)

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

@@ -30,11 +30,6 @@ func newSqlPreferenceStore(sqlStore *SqlStore) store.PreferenceStore {
return s
}
func (s SqlPreferenceStore) createIndexesIfNotExists() {
s.CreateIndexIfNotExists("idx_preferences_category", "Preferences", "Category")
s.CreateIndexIfNotExists("idx_preferences_name", "Preferences", "Name")
}
func (s SqlPreferenceStore) deleteUnusedFeatures() {
mlog.Debug("Deleting any unused pre-release features")
sql, args, err := s.getQueryBuilder().

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

@@ -29,11 +29,6 @@ func newSqlProductNoticesStore(sqlStore *SqlStore) store.ProductNoticesStore {
return s
}
func (s SqlProductNoticesStore) createIndexesIfNotExists() {
s.CreateIndexIfNotExists("idx_notice_views_timestamp", "ProductNoticeViewState", "Timestamp")
s.CreateIndexIfNotExists("idx_notice_views_notice_id", "ProductNoticeViewState", "NoticeId")
}
func (s SqlProductNoticesStore) Clear(notices []string) error {
sql, args, err := s.getQueryBuilder().Delete("ProductNoticeViewState").Where(sq.Eq{"NoticeId": notices}).ToSql()
if err != nil {

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

@@ -200,11 +200,3 @@ func (s sqlRemoteClusterStore) SetLastPingAt(remoteClusterId string) error {
}
return nil
}
func (s *sqlRemoteClusterStore) createIndexesIfNotExists() {
uniquenessColumns := []string{"SiteUrl", "RemoteTeamId"}
if s.DriverName() == model.DatabaseDriverMysql {
uniquenessColumns = []string{"RemoteTeamId", "SiteUrl(168)"}
}
s.CreateUniqueCompositeIndexIfNotExists(RemoteClusterSiteURLUniqueIndex, "RemoteClusters", uniquenessColumns)
}

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

@@ -49,14 +49,6 @@ func newSqlRetentionPolicyStore(sqlStore *SqlStore, metrics einterfaces.MetricsI
return s
}
func (s *SqlRetentionPolicyStore) createIndexesIfNotExists() {
s.CreateIndexIfNotExists("IDX_RetentionPolicies_DisplayName", "RetentionPolicies", "DisplayName")
s.CreateIndexIfNotExists("IDX_RetentionPoliciesChannels_PolicyId", "RetentionPoliciesChannels", "PolicyId")
s.CreateIndexIfNotExists("IDX_RetentionPoliciesTeams_PolicyId", "RetentionPoliciesTeams", "PolicyId")
s.CreateForeignKeyIfNotExists("RetentionPoliciesChannels", "PolicyId", "RetentionPolicies", "Id", true)
s.CreateForeignKeyIfNotExists("RetentionPoliciesTeams", "PolicyId", "RetentionPolicies", "Id", true)
}
// executePossiblyEmptyQuery only executes the query if it is non-empty. This helps avoid
// having to check for MySQL, which, unlike Postgres, does not allow empty queries.
func executePossiblyEmptyQuery(txn *sqlxTxWrapper, query string, args ...interface{}) (sql.Result, error) {

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

@@ -43,12 +43,6 @@ func newSqlSchemeStore(sqlStore *SqlStore) store.SchemeStore {
return s
}
func (s SqlSchemeStore) createIndexesIfNotExists() {
s.CreateIndexIfNotExists("idx_schemes_channel_guest_role", "Schemes", "DefaultChannelGuestRole")
s.CreateIndexIfNotExists("idx_schemes_channel_user_role", "Schemes", "DefaultChannelUserRole")
s.CreateIndexIfNotExists("idx_schemes_channel_admin_role", "Schemes", "DefaultChannelAdminRole")
}
func (s *SqlSchemeStore) Save(scheme *model.Scheme) (*model.Scheme, error) {
if scheme.Id == "" {
transaction, err := s.GetMasterX().Beginx()

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

@@ -40,14 +40,6 @@ func newSqlSessionStore(sqlStore *SqlStore) store.SessionStore {
return us
}
func (me SqlSessionStore) createIndexesIfNotExists() {
me.CreateIndexIfNotExists("idx_sessions_user_id", "Sessions", "UserId")
me.CreateIndexIfNotExists("idx_sessions_token", "Sessions", "Token")
me.CreateIndexIfNotExists("idx_sessions_expires_at", "Sessions", "ExpiresAt")
me.CreateIndexIfNotExists("idx_sessions_create_at", "Sessions", "CreateAt")
me.CreateIndexIfNotExists("idx_sessions_last_activity_at", "Sessions", "LastActivityAt")
}
func (me SqlSessionStore) Save(session *model.Session) (*model.Session, error) {
if session.Id != "" {
return nil, store.NewErrInvalidInput("Session", "id", session.Id)

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

@@ -64,10 +64,6 @@ func newSqlSharedChannelStore(sqlStore *SqlStore) store.SharedChannelStore {
return s
}
func (s SqlSharedChannelStore) createIndexesIfNotExists() {
s.CreateIndexIfNotExists("idx_sharedchannelusers_remote_id", "SharedChannelUsers", "RemoteId")
}
// Save inserts a new shared channel record.
func (s SqlSharedChannelStore) Save(sc *model.SharedChannel) (*model.SharedChannel, error) {
sc.PreSave()

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

@@ -33,10 +33,6 @@ func newSqlStatusStore(sqlStore *SqlStore) store.StatusStore {
return s
}
func (s SqlStatusStore) createIndexesIfNotExists() {
s.CreateCompositeIndexIfNotExists("idx_status_status_dndendtime", "Status", []string{"Status", "DNDEndTime"})
}
func (s SqlStatusStore) SaveOrUpdate(st *model.Status) error {
query := s.getQueryBuilder().
Insert("Status").

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

@@ -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) {

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

@@ -489,7 +489,6 @@ func TestUpAndDownMigrations(t *testing.T) {
for _, driver := range testDrivers {
t.Run("Should be reversible for "+driver, func(t *testing.T) {
t.Parallel()
settings := makeSqlSettings(driver)
store := New(*settings, nil)
defer store.Close()

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

@@ -30,9 +30,6 @@ func newSqlTermsOfServiceStore(sqlStore *SqlStore, metrics einterfaces.MetricsIn
return s
}
func (s SqlTermsOfServiceStore) createIndexesIfNotExists() {
}
func (s SqlTermsOfServiceStore) Save(termsOfService *model.TermsOfService) (*model.TermsOfService, error) {
if termsOfService.Id != "" {
return nil, store.NewErrInvalidInput("TermsOfService", "Id", termsOfService.Id)

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

@@ -57,13 +57,6 @@ func threadToSlice(thread *model.Thread) []interface{} {
}
}
func (s *SqlThreadStore) createIndexesIfNotExists() {
s.CreateIndexIfNotExists("idx_thread_memberships_last_update_at", "ThreadMemberships", "LastUpdated")
s.CreateIndexIfNotExists("idx_thread_memberships_last_view_at", "ThreadMemberships", "LastViewed")
s.CreateIndexIfNotExists("idx_thread_memberships_user_id", "ThreadMemberships", "UserId")
s.CreateCompositeIndexIfNotExists("idx_threads_channel_id_last_reply_at", "Threads", []string{"ChannelId", "LastReplyAt"})
}
func (s *SqlThreadStore) SaveMultiple(threads []*model.Thread) ([]*model.Thread, int, error) {
builder := s.getQueryBuilder().Insert("Threads").Columns(threadSliceColumns()...)
for _, thread := range threads {

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

@@ -32,9 +32,6 @@ func newSqlTokenStore(sqlStore *SqlStore) store.TokenStore {
return s
}
func (s SqlTokenStore) createIndexesIfNotExists() {
}
func (s SqlTokenStore) Save(token *model.Token) error {
if err := token.IsValid(); err != nil {
return err

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

@@ -5,14 +5,11 @@ package sqlstore
import (
"database/sql"
"encoding/json"
"strings"
"github.com/blang/semver"
"github.com/pkg/errors"
"github.com/mattermost/mattermost-server/v6/model"
"github.com/mattermost/mattermost-server/v6/services/timezones"
"github.com/mattermost/mattermost-server/v6/shared/mlog"
)
@@ -260,7 +257,6 @@ func shouldPerformUpgrade(sqlStore *SqlStore, currentSchemaVersion string, expec
func upgradeDatabaseToVersion31(sqlStore *SqlStore) {
if shouldPerformUpgrade(sqlStore, Version300, Version310) {
sqlStore.CreateColumnIfNotExists("OutgoingWebhooks", "ContentType", "varchar(128)", "varchar(128)", "")
saveSchemaVersion(sqlStore, Version310)
}
}
@@ -289,19 +285,6 @@ func upgradeDatabaseToVersion33(sqlStore *SqlStore) {
}
defer finalizeTransaction(transaction)
// increase size of Value column of Preferences table to match the size of the ThemeProps column
if sqlStore.DriverName() == model.DatabaseDriverPostgres {
if _, err := transaction.ExecNoTimeout("ALTER TABLE Preferences ALTER COLUMN Value TYPE varchar(2000)"); err != nil {
themeMigrationFailed(err)
return
}
} else if sqlStore.DriverName() == model.DatabaseDriverMysql {
if _, err := transaction.ExecNoTimeout("ALTER TABLE Preferences MODIFY Value text"); err != nil {
themeMigrationFailed(err)
return
}
}
// copy data across
if _, err := transaction.ExecNoTimeout(
`INSERT INTO
@@ -326,64 +309,28 @@ func upgradeDatabaseToVersion33(sqlStore *SqlStore) {
themeMigrationFailed(err)
return
}
// rename solarized_* code themes to solarized-* to match client changes in 3.0
var data model.Preferences
if _, err := sqlStore.GetMaster().Select(&data, "SELECT * FROM Preferences WHERE Category = '"+model.PreferenceCategoryTheme+"' AND Value LIKE '%solarized_%'"); err == nil {
for i := range data {
data[i].Value = strings.Replace(data[i].Value, "solarized_", "solarized-", -1)
}
sqlStore.Preference().Save(data)
}
}
sqlStore.CreateColumnIfNotExists("OAuthApps", "IsTrusted", "tinyint(1)", "boolean", "0")
sqlStore.CreateColumnIfNotExists("OAuthApps", "IconURL", "varchar(512)", "varchar(512)", "")
sqlStore.CreateColumnIfNotExists("OAuthAccessData", "ClientId", "varchar(26)", "varchar(26)", "")
sqlStore.CreateColumnIfNotExists("OAuthAccessData", "UserId", "varchar(26)", "varchar(26)", "")
sqlStore.CreateColumnIfNotExists("OAuthAccessData", "ExpiresAt", "bigint", "bigint", "0")
if sqlStore.DoesColumnExist("OAuthAccessData", "AuthCode") {
sqlStore.RemoveIndexIfExists("idx_oauthaccessdata_auth_code", "OAuthAccessData")
sqlStore.RemoveColumnIfExists("OAuthAccessData", "AuthCode")
}
sqlStore.RemoveColumnIfExists("Users", "LastActivityAt")
sqlStore.RemoveColumnIfExists("Users", "LastPingAt")
sqlStore.CreateColumnIfNotExists("OutgoingWebhooks", "TriggerWhen", "tinyint", "integer", "0")
saveSchemaVersion(sqlStore, Version330)
}
}
func upgradeDatabaseToVersion34(sqlStore *SqlStore) {
if shouldPerformUpgrade(sqlStore, Version330, Version340) {
sqlStore.CreateColumnIfNotExists("Status", "Manual", "BOOLEAN", "BOOLEAN", "0")
sqlStore.CreateColumnIfNotExists("Status", "ActiveChannel", "varchar(26)", "varchar(26)", "")
saveSchemaVersion(sqlStore, Version340)
}
}
func upgradeDatabaseToVersion35(sqlStore *SqlStore) {
if shouldPerformUpgrade(sqlStore, Version340, Version350) {
sqlStore.GetMaster().ExecNoTimeout("UPDATE Users SET Roles = 'system_user' WHERE Roles = ''")
sqlStore.GetMaster().ExecNoTimeout("UPDATE Users SET Roles = 'system_user system_admin' WHERE Roles = 'system_admin'")
sqlStore.GetMaster().ExecNoTimeout("UPDATE TeamMembers SET Roles = 'team_user' WHERE Roles = ''")
sqlStore.GetMaster().ExecNoTimeout("UPDATE TeamMembers SET Roles = 'team_user team_admin' WHERE Roles = 'admin'")
sqlStore.GetMaster().ExecNoTimeout("UPDATE ChannelMembers SET Roles = 'channel_user' WHERE Roles = ''")
sqlStore.GetMaster().ExecNoTimeout("UPDATE ChannelMembers SET Roles = 'channel_user channel_admin' WHERE Roles = 'admin'")
sqlStore.GetMaster().Exec("UPDATE TeamMembers SET Roles = 'team_user' WHERE Roles = ''")
sqlStore.GetMaster().Exec("UPDATE TeamMembers SET Roles = 'team_user team_admin' WHERE Roles = 'admin'")
sqlStore.GetMaster().Exec("UPDATE ChannelMembers SET Roles = 'channel_user' WHERE Roles = ''")
sqlStore.GetMaster().Exec("UPDATE ChannelMembers SET Roles = 'channel_user channel_admin' WHERE Roles = 'admin'")
// The rest of the migration from Filenames -> FileIds is done lazily in api.GetFileInfosForPost
sqlStore.CreateColumnIfNotExists("Posts", "FileIds", "varchar(150)", "varchar(150)", "[]")
// Increase maximum length of the Channel table Purpose column.
if sqlStore.GetMaxLengthOfColumnIfExists("Channels", "Purpose") != "250" {
sqlStore.AlterColumnTypeIfExists("Channels", "Purpose", "varchar(250)", "varchar(250)")
}
sqlStore.Session().RemoveAllSessions()
saveSchemaVersion(sqlStore, Version350)
@@ -392,39 +339,24 @@ func upgradeDatabaseToVersion35(sqlStore *SqlStore) {
func upgradeDatabaseToVersion36(sqlStore *SqlStore) {
if shouldPerformUpgrade(sqlStore, Version350, Version360) {
sqlStore.CreateColumnIfNotExists("Posts", "HasReactions", "tinyint", "boolean", "0")
// Add a Position column to users.
sqlStore.CreateColumnIfNotExists("Users", "Position", "varchar(64)", "varchar(64)", "")
// Remove ActiveChannel column from Status
sqlStore.RemoveColumnIfExists("Status", "ActiveChannel")
saveSchemaVersion(sqlStore, Version360)
}
}
func upgradeDatabaseToVersion37(sqlStore *SqlStore) {
if shouldPerformUpgrade(sqlStore, Version360, Version370) {
// Add EditAt column to Posts
sqlStore.CreateColumnIfNotExists("Posts", "EditAt", " bigint", " bigint", "0")
saveSchemaVersion(sqlStore, Version370)
}
}
func upgradeDatabaseToVersion38(sqlStore *SqlStore) {
if shouldPerformUpgrade(sqlStore, Version370, Version380) {
// Add the IsPinned column to posts.
sqlStore.CreateColumnIfNotExists("Posts", "IsPinned", "boolean", "boolean", "0")
saveSchemaVersion(sqlStore, Version380)
}
}
func upgradeDatabaseToVersion39(sqlStore *SqlStore) {
if shouldPerformUpgrade(sqlStore, Version380, Version390) {
sqlStore.CreateColumnIfNotExists("OAuthAccessData", "Scope", "varchar(128)", "varchar(128)", model.DefaultScope)
sqlStore.RemoveTableIfExists("PasswordRecovery")
saveSchemaVersion(sqlStore, Version390)
@@ -445,11 +377,6 @@ func upgradeDatabaseToVersion40(sqlStore *SqlStore) {
func upgradeDatabaseToVersion41(sqlStore *SqlStore) {
if shouldPerformUpgrade(sqlStore, Version400, Version410) {
// Increase maximum length of the Users table Roles column.
if sqlStore.GetMaxLengthOfColumnIfExists("Users", "Roles") != "256" {
sqlStore.AlterColumnTypeIfExists("Users", "Roles", "varchar(256)", "varchar(256)")
}
sqlStore.RemoveTableIfExists("JobStatuses")
saveSchemaVersion(sqlStore, Version410)
@@ -470,9 +397,6 @@ func upgradeDatabaseToVersion43(sqlStore *SqlStore) {
func upgradeDatabaseToVersion44(sqlStore *SqlStore) {
if shouldPerformUpgrade(sqlStore, Version430, Version440) {
// Add the IsActive column to UserAccessToken.
sqlStore.CreateColumnIfNotExists("UserAccessTokens", "IsActive", "boolean", "boolean", "1")
saveSchemaVersion(sqlStore, Version440)
}
}
@@ -485,35 +409,24 @@ func upgradeDatabaseToVersion45(sqlStore *SqlStore) {
func upgradeDatabaseToVersion46(sqlStore *SqlStore) {
if shouldPerformUpgrade(sqlStore, Version450, Version460) {
sqlStore.CreateColumnIfNotExists("IncomingWebhooks", "Username", "varchar(64)", "varchar(64)", "")
sqlStore.CreateColumnIfNotExists("IncomingWebhooks", "IconURL", "varchar(1024)", "varchar(1024)", "")
saveSchemaVersion(sqlStore, Version460)
}
}
func upgradeDatabaseToVersion47(sqlStore *SqlStore) {
if shouldPerformUpgrade(sqlStore, Version460, Version470) {
sqlStore.AlterColumnTypeIfExists("Users", "Position", "varchar(128)", "varchar(128)")
sqlStore.AlterColumnTypeIfExists("OAuthAuthData", "State", "varchar(1024)", "varchar(1024)")
sqlStore.RemoveColumnIfExists("ChannelMemberHistory", "Email")
sqlStore.RemoveColumnIfExists("ChannelMemberHistory", "Username")
saveSchemaVersion(sqlStore, Version470)
}
}
func upgradeDatabaseToVersion471(sqlStore *SqlStore) {
// If any new instances started with 4.7, they would have the bad Email column on the
// ChannelMemberHistory table. So for those cases we need to do an upgrade between
// 4.7.0 and 4.7.1
if shouldPerformUpgrade(sqlStore, Version470, Version471) {
sqlStore.RemoveColumnIfExists("ChannelMemberHistory", "Email")
saveSchemaVersion(sqlStore, Version471)
}
}
func upgradeDatabaseToVersion472(sqlStore *SqlStore) {
if shouldPerformUpgrade(sqlStore, Version471, Version472) {
sqlStore.RemoveIndexIfExists("idx_channels_displayname", "Channels")
saveSchemaVersion(sqlStore, Version472)
}
}
@@ -526,7 +439,6 @@ func upgradeDatabaseToVersion48(sqlStore *SqlStore) {
func upgradeDatabaseToVersion481(sqlStore *SqlStore) {
if shouldPerformUpgrade(sqlStore, Version480, Version481) {
sqlStore.RemoveIndexIfExists("idx_channels_displayname", "Channels")
saveSchemaVersion(sqlStore, Version481)
}
}
@@ -537,26 +449,13 @@ func upgradeDatabaseToVersion49(sqlStore *SqlStore) {
// in the file `app/app.go` in the function `DoAdvancedPermissionsMigration()`.
if shouldPerformUpgrade(sqlStore, Version481, Version490) {
defaultTimezone := timezones.DefaultUserTimezone()
defaultTimezoneValue, err := json.Marshal(defaultTimezone)
if err != nil {
mlog.Fatal(err.Error())
}
sqlStore.CreateColumnIfNotExists("Users", "Timezone", "varchar(256)", "varchar(256)", string(defaultTimezoneValue))
sqlStore.RemoveIndexIfExists("idx_channels_displayname", "Channels")
saveSchemaVersion(sqlStore, Version490)
}
}
func upgradeDatabaseToVersion410(sqlStore *SqlStore) {
if shouldPerformUpgrade(sqlStore, Version490, Version4100) {
sqlStore.RemoveIndexIfExists("Name_2", "Channels")
sqlStore.RemoveIndexIfExists("Name_2", "Emoji")
sqlStore.RemoveIndexIfExists("ClientId_2", "OAuthAccessData")
saveSchemaVersion(sqlStore, Version4100)
sqlStore.GetMaster().ExecNoTimeout("UPDATE Users SET AuthData=LOWER(AuthData) WHERE AuthService = 'saml'")
}
}
@@ -579,18 +478,6 @@ func upgradeDatabaseToVersion50(sqlStore *SqlStore) {
// DELETE from Systems WHERE Name = 'migration_advanced_permissions_phase_2';
if shouldPerformUpgrade(sqlStore, Version4100, Version500) {
sqlStore.CreateColumnIfNotExistsNoDefault("Channels", "SchemeId", "varchar(26)", "varchar(26)")
sqlStore.CreateColumnIfNotExistsNoDefault("ChannelMembers", "SchemeUser", "boolean", "boolean")
sqlStore.CreateColumnIfNotExistsNoDefault("ChannelMembers", "SchemeAdmin", "boolean", "boolean")
sqlStore.CreateColumnIfNotExists("Roles", "BuiltIn", "boolean", "boolean", "0")
sqlStore.GetMaster().ExecNoTimeout("UPDATE Roles SET BuiltIn=true")
sqlStore.GetMaster().ExecNoTimeout("UPDATE Roles SET SchemeManaged=false WHERE Name NOT IN ('system_user', 'system_admin', 'team_user', 'team_admin', 'channel_user', 'channel_admin')")
sqlStore.CreateColumnIfNotExists("IncomingWebhooks", "ChannelLocked", "boolean", "boolean", "0")
sqlStore.RemoveIndexIfExists("idx_channels_txt", "Channels")
saveSchemaVersion(sqlStore, Version500)
}
}
@@ -603,8 +490,6 @@ func upgradeDatabaseToVersion51(sqlStore *SqlStore) {
func upgradeDatabaseToVersion52(sqlStore *SqlStore) {
if shouldPerformUpgrade(sqlStore, Version510, Version520) {
sqlStore.CreateColumnIfNotExists("OutgoingWebhooks", "Username", "varchar(64)", "varchar(64)", "")
sqlStore.CreateColumnIfNotExists("OutgoingWebhooks", "IconURL", "varchar(1024)", "varchar(1024)", "")
saveSchemaVersion(sqlStore, Version520)
}
}
@@ -617,11 +502,6 @@ func upgradeDatabaseToVersion53(sqlStore *SqlStore) {
func upgradeDatabaseToVersion54(sqlStore *SqlStore) {
if shouldPerformUpgrade(sqlStore, Version530, Version540) {
sqlStore.AlterColumnTypeIfExists("OutgoingWebhooks", "Description", "varchar(500)", "varchar(500)")
sqlStore.AlterColumnTypeIfExists("IncomingWebhooks", "Description", "varchar(500)", "varchar(500)")
if err := sqlStore.Channel().MigratePublicChannels(); err != nil {
mlog.Fatal("Failed to migrate PublicChannels table", mlog.Err(err))
}
saveSchemaVersion(sqlStore, Version540)
}
}
@@ -634,19 +514,6 @@ func upgradeDatabaseToVersion55(sqlStore *SqlStore) {
func upgradeDatabaseToVersion56(sqlStore *SqlStore) {
if shouldPerformUpgrade(sqlStore, Version550, Version560) {
sqlStore.CreateColumnIfNotExists("PluginKeyValueStore", "ExpireAt", "bigint(20)", "bigint", "0")
// migrating user's accepted terms of service data into the new table
sqlStore.GetMaster().ExecNoTimeout("INSERT INTO UserTermsOfService SELECT Id, AcceptedTermsOfServiceId as TermsOfServiceId, :CreateAt FROM Users WHERE AcceptedTermsOfServiceId != \"\" AND AcceptedTermsOfServiceId IS NOT NULL", map[string]interface{}{"CreateAt": model.GetMillis()})
if sqlStore.DriverName() == model.DatabaseDriverPostgres {
sqlStore.RemoveIndexIfExists("idx_users_email_lower", "lower(Email)")
sqlStore.RemoveIndexIfExists("idx_users_username_lower", "lower(Username)")
sqlStore.RemoveIndexIfExists("idx_users_nickname_lower", "lower(Nickname)")
sqlStore.RemoveIndexIfExists("idx_users_firstname_lower", "lower(FirstName)")
sqlStore.RemoveIndexIfExists("idx_users_lastname_lower", "lower(LastName)")
}
saveSchemaVersion(sqlStore, Version560)
}
@@ -660,11 +527,6 @@ func upgradeDatabaseToVersion57(sqlStore *SqlStore) {
func upgradeDatabaseToVersion58(sqlStore *SqlStore) {
if shouldPerformUpgrade(sqlStore, Version570, Version580) {
// idx_channels_txt was removed in `upgradeDatabaseToVersion50`, but merged as part of
// v5.1, so the migration wouldn't apply to anyone upgrading from v5.0. Remove it again to
// bring the upgraded (from v5.0) and fresh install schemas back in sync.
sqlStore.RemoveIndexIfExists("idx_channels_txt", "Channels")
// Fix column types and defaults where gorp converged on a different schema value than the
// original migration.
sqlStore.AlterColumnTypeIfExists("OutgoingWebhooks", "Description", "text", "VARCHAR(500)")
@@ -675,7 +537,6 @@ func upgradeDatabaseToVersion58(sqlStore *SqlStore) {
sqlStore.RemoveDefaultIfColumnExists("OutgoingWebhooks", "IconURL")
}
sqlStore.AlterDefaultIfColumnExists("OutgoingWebhooks", "Username", model.NewString("NULL"), nil)
sqlStore.AlterDefaultIfColumnExists("PluginKeyValueStore", "ExpireAt", model.NewString("NULL"), model.NewString("NULL"))
saveSchemaVersion(sqlStore, Version580)
}
@@ -689,9 +550,6 @@ func upgradeDatabaseToVersion59(sqlStore *SqlStore) {
func upgradeDatabaseToVersion510(sqlStore *SqlStore) {
if shouldPerformUpgrade(sqlStore, Version590, Version5100) {
sqlStore.CreateColumnIfNotExistsNoDefault("Channels", "GroupConstrained", "tinyint(4)", "boolean")
sqlStore.CreateIndexIfNotExists("idx_groupteams_teamid", "GroupTeams", "TeamId")
sqlStore.CreateIndexIfNotExists("idx_groupchannels_channelid", "GroupChannels", "ChannelId")
saveSchemaVersion(sqlStore, Version5100)
@@ -719,24 +577,12 @@ func upgradeDatabaseToVersion511(sqlStore *SqlStore) {
func upgradeDatabaseToVersion512(sqlStore *SqlStore) {
if shouldPerformUpgrade(sqlStore, Version5110, Version5120) {
sqlStore.CreateColumnIfNotExistsNoDefault("ChannelMembers", "SchemeGuest", "boolean", "boolean")
sqlStore.CreateColumnIfNotExistsNoDefault("Schemes", "DefaultTeamGuestRole", "text", "VARCHAR(64)")
sqlStore.CreateColumnIfNotExistsNoDefault("Schemes", "DefaultChannelGuestRole", "text", "VARCHAR(64)")
sqlStore.GetMaster().ExecNoTimeout("UPDATE Schemes SET DefaultTeamGuestRole = '', DefaultChannelGuestRole = ''")
// Saturday, January 24, 2065 5:20:00 AM GMT. To remove all personal access token sessions.
sqlStore.GetMaster().ExecNoTimeout("DELETE FROM Sessions WHERE ExpiresAt > 3000000000000")
saveSchemaVersion(sqlStore, Version5120)
}
}
func upgradeDatabaseToVersion513(sqlStore *SqlStore) {
if shouldPerformUpgrade(sqlStore, Version5120, Version5130) {
// The previous jobs ran once per minute, cluttering the Jobs table with somewhat useless entries. Clean that up.
sqlStore.GetMaster().ExecNoTimeout("DELETE FROM Jobs WHERE Type = 'plugins'")
saveSchemaVersion(sqlStore, Version5130)
}
}
@@ -755,18 +601,8 @@ func upgradeDatabaseToVersion515(sqlStore *SqlStore) {
func upgradeDatabaseToVersion516(sqlStore *SqlStore) {
if shouldPerformUpgrade(sqlStore, Version5150, Version5160) {
if sqlStore.DriverName() == model.DatabaseDriverPostgres {
sqlStore.GetMaster().ExecNoTimeout("ALTER TABLE Tokens ALTER COLUMN Extra TYPE varchar(2048)")
} else if sqlStore.DriverName() == model.DatabaseDriverMysql {
sqlStore.GetMaster().ExecNoTimeout("ALTER TABLE Tokens MODIFY Extra text")
}
saveSchemaVersion(sqlStore, Version5160)
// Fix mismatches between the canonical and migrated schemas.
sqlStore.AlterColumnTypeIfExists("Schemes", "DefaultTeamGuestRole", "varchar(64)", "VARCHAR(64)")
sqlStore.AlterColumnTypeIfExists("Schemes", "DefaultChannelGuestRole", "varchar(64)", "VARCHAR(64)")
sqlStore.AlterColumnTypeIfExists("Teams", "AllowedDomains", "text", "VARCHAR(1000)")
sqlStore.AlterColumnTypeIfExists("Channels", "GroupConstrained", "tinyint(1)", "boolean")
sqlStore.AlterColumnTypeIfExists("Teams", "GroupConstrained", "tinyint(1)", "boolean")
// One known mismatch remains: ChannelMembers.SchemeGuest. The requisite migration
@@ -774,8 +610,9 @@ func upgradeDatabaseToVersion516(sqlStore *SqlStore) {
// table rewrite in most MySQL and Postgres instances.
// sqlStore.AlterColumnTypeIfExists("ChannelMembers", "SchemeGuest", "tinyint(4)", "boolean")
sqlStore.CreateIndexIfNotExists("idx_groupteams_teamid", "GroupTeams", "TeamId")
sqlStore.CreateIndexIfNotExists("idx_groupchannels_channelid", "GroupChannels", "ChannelId")
saveSchemaVersion(sqlStore, Version5160)
}
}
@@ -799,14 +636,6 @@ func upgradeDatabaseToVersion519(sqlStore *SqlStore) {
func upgradeDatabaseToVersion520(sqlStore *SqlStore) {
if shouldPerformUpgrade(sqlStore, Version5190, Version5200) {
sqlStore.CreateColumnIfNotExistsNoDefault("Bots", "LastIconUpdate", "bigint", "bigint")
sqlStore.CreateColumnIfNotExists("GroupTeams", "SchemeAdmin", "boolean", "boolean", "0")
sqlStore.CreateIndexIfNotExists("idx_groupteams_schemeadmin", "GroupTeams", "SchemeAdmin")
sqlStore.CreateColumnIfNotExists("GroupChannels", "SchemeAdmin", "boolean", "boolean", "0")
sqlStore.CreateIndexIfNotExists("idx_groupchannels_schemeadmin", "GroupChannels", "SchemeAdmin")
saveSchemaVersion(sqlStore, Version5200)
}
}
@@ -820,10 +649,6 @@ func upgradeDatabaseToVersion521(sqlStore *SqlStore) {
func upgradeDatabaseToVersion522(sqlStore *SqlStore) {
if shouldPerformUpgrade(sqlStore, Version5210, Version5220) {
sqlStore.CreateIndexIfNotExists("idx_teams_scheme_id", "Teams", "SchemeId")
sqlStore.CreateIndexIfNotExists("idx_channels_scheme_id", "Channels", "SchemeId")
sqlStore.CreateIndexIfNotExists("idx_schemes_channel_guest_role", "Schemes", "DefaultChannelGuestRole")
sqlStore.CreateIndexIfNotExists("idx_schemes_channel_user_role", "Schemes", "DefaultChannelUserRole")
sqlStore.CreateIndexIfNotExists("idx_schemes_channel_admin_role", "Schemes", "DefaultChannelAdminRole")
saveSchemaVersion(sqlStore, Version5220)
}
@@ -837,10 +662,6 @@ func upgradeDatabaseToVersion523(sqlStore *SqlStore) {
func upgradeDatabaseToVersion524(sqlStore *SqlStore) {
if shouldPerformUpgrade(sqlStore, Version5230, Version5240) {
sqlStore.CreateColumnIfNotExists("UserGroups", "AllowReference", "boolean", "boolean", "0")
sqlStore.GetMaster().ExecNoTimeout("UPDATE UserGroups SET Name = null, AllowReference = false")
sqlStore.AlterPrimaryKey("Reactions", []string{"PostId", "UserId", "EmojiName"})
saveSchemaVersion(sqlStore, Version5240)
}
}
@@ -853,8 +674,6 @@ func upgradeDatabaseToVersion525(sqlStore *SqlStore) {
func upgradeDatabaseToVersion526(sqlStore *SqlStore) {
if shouldPerformUpgrade(sqlStore, Version5250, Version5260) {
sqlStore.CreateColumnIfNotExists("Sessions", "ExpiredNotify", "boolean", "boolean", "0")
saveSchemaVersion(sqlStore, Version5260)
}
}
@@ -871,13 +690,8 @@ func upgradeDatabaseToVersion528(sqlStore *SqlStore) {
mlog.Fatal("Error upgrading DB schema to 5.28.0", mlog.Err(err))
}
sqlStore.CreateColumnIfNotExistsNoDefault("Commands", "PluginId", "VARCHAR(190)", "VARCHAR(190)")
sqlStore.GetMaster().ExecNoTimeout("UPDATE Commands SET PluginId = '' WHERE PluginId IS NULL")
sqlStore.AlterColumnTypeIfExists("Teams", "Type", "VARCHAR(255)", "VARCHAR(255)")
sqlStore.AlterColumnTypeIfExists("Teams", "SchemeId", "VARCHAR(26)", "VARCHAR(26)")
sqlStore.AlterColumnTypeIfExists("IncomingWebhooks", "Username", "varchar(255)", "varchar(255)")
sqlStore.AlterColumnTypeIfExists("IncomingWebhooks", "IconURL", "text", "varchar(1024)")
saveSchemaVersion(sqlStore, Version5280)
}
@@ -885,8 +699,6 @@ func upgradeDatabaseToVersion528(sqlStore *SqlStore) {
func upgradeDatabaseToVersion5281(sqlStore *SqlStore) {
if shouldPerformUpgrade(sqlStore, Version5280, Version5281) {
sqlStore.CreateColumnIfNotExistsNoDefault("FileInfo", "MiniPreview", "MEDIUMBLOB", "bytea")
saveSchemaVersion(sqlStore, Version5281)
}
}
@@ -904,18 +716,6 @@ func precheckMigrationToVersion528(sqlStore *SqlStore) error {
if err != nil {
return err
}
webhooksQuery, _, err := sqlStore.getQueryBuilder().Select(`COALESCE(SUM(CASE
WHEN CHAR_LENGTH(Username) > 255 THEN 1
ELSE 0
END),0) as usernamewrong,
COALESCE(SUM(CASE
WHEN CHAR_LENGTH(IconURL) > 1024 THEN 1
ELSE 0
END),0) as iconurlwrong`).
From("IncomingWebhooks").ToSql()
if err != nil {
return err
}
var schemeIDWrong, typeWrong int
row := sqlStore.GetMaster().Db.QueryRow(teamsQuery)
@@ -929,38 +729,11 @@ func precheckMigrationToVersion528(sqlStore *SqlStore) error {
"Teams column Type has data larger that 255 characters")
}
var usernameWrong, iconURLWrong int
row = sqlStore.GetMaster().Db.QueryRow(webhooksQuery)
if err = row.Scan(&usernameWrong, &iconURLWrong); err != nil && err != sql.ErrNoRows {
mlog.Error("Error fetching IncomingWebhooks columns data", mlog.Err(err))
} else if err == nil && usernameWrong > 0 {
return errors.New("Migration failure: " +
"IncomingWebhooks column Username has data larger that 255 characters")
} else if err == nil && iconURLWrong > 0 {
return errors.New("Migration failure: " +
"IncomingWebhooks column IconURL has data larger that 1024 characters")
}
return nil
}
func upgradeDatabaseToVersion529(sqlStore *SqlStore) {
if shouldPerformUpgrade(sqlStore, Version5281, Version5290) {
sqlStore.AlterColumnTypeIfExists("SidebarCategories", "Id", "VARCHAR(128)", "VARCHAR(128)")
sqlStore.RemoveDefaultIfColumnExists("SidebarCategories", "Id")
sqlStore.AlterColumnTypeIfExists("SidebarChannels", "CategoryId", "VARCHAR(128)", "VARCHAR(128)")
sqlStore.RemoveDefaultIfColumnExists("SidebarChannels", "CategoryId")
sqlStore.CreateColumnIfNotExistsNoDefault("Threads", "ChannelId", "VARCHAR(26)", "VARCHAR(26)")
updateThreadChannelsQuery := "UPDATE Threads INNER JOIN Posts ON Posts.Id=Threads.PostId SET Threads.ChannelId=Posts.ChannelId WHERE Threads.ChannelId IS NULL"
if sqlStore.DriverName() == model.DatabaseDriverPostgres {
updateThreadChannelsQuery = "UPDATE Threads SET ChannelId=Posts.ChannelId FROM Posts WHERE Posts.Id=Threads.PostId AND Threads.ChannelId IS NULL"
}
if _, err := sqlStore.GetMaster().ExecNoTimeout(updateThreadChannelsQuery); err != nil {
mlog.Error("Error updating ChannelId in Threads table", mlog.Err(err))
}
saveSchemaVersion(sqlStore, Version5290)
}
}
@@ -973,10 +746,6 @@ func upgradeDatabaseToVersion5291(sqlStore *SqlStore) {
func upgradeDatabaseToVersion530(sqlStore *SqlStore) {
if shouldPerformUpgrade(sqlStore, Version5291, Version5300) {
sqlStore.CreateColumnIfNotExistsNoDefault("FileInfo", "Content", "longtext", "text")
sqlStore.CreateColumnIfNotExists("SidebarCategories", "Muted", "tinyint(1)", "boolean", "0")
saveSchemaVersion(sqlStore, Version5300)
}
}
@@ -1006,22 +775,6 @@ func hasMissingMigrationsVersion532(sqlStore *SqlStore) bool {
}
}
if !sqlStore.DoesColumnExist("Channels", "Shared") {
return true
}
if !sqlStore.DoesColumnExist("ThreadMemberships", "UnreadMentions") {
return true
}
if !sqlStore.DoesColumnExist("Reactions", "UpdateAt") {
return true
}
if !sqlStore.DoesColumnExist("Reactions", "DeleteAt") {
return true
}
return false
}
@@ -1033,12 +786,6 @@ func upgradeDatabaseToVersion532(sqlStore *SqlStore) {
// allow 10 files per post
sqlStore.AlterColumnTypeIfExists("Posts", "FileIds", "text", "varchar(300)")
}
sqlStore.CreateColumnIfNotExists("ThreadMemberships", "UnreadMentions", "bigint", "bigint", "0")
// Shared channels support
sqlStore.CreateColumnIfNotExistsNoDefault("Channels", "Shared", "tinyint(1)", "boolean")
sqlStore.CreateColumnIfNotExistsNoDefault("Reactions", "UpdateAt", "bigint", "bigint")
sqlStore.CreateColumnIfNotExistsNoDefault("Reactions", "DeleteAt", "bigint", "bigint")
}
if shouldPerformUpgrade(sqlStore, Version5310, Version5320) {
@@ -1060,27 +807,10 @@ func upgradeDatabaseToVersion534(sqlStore *SqlStore) {
func upgradeDatabaseToVersion535(sqlStore *SqlStore) {
if shouldPerformUpgrade(sqlStore, Version5340, Version5350) {
sqlStore.AlterColumnTypeIfExists("Roles", "Permissions", "longtext", "text")
sqlStore.CreateColumnIfNotExists("SidebarCategories", "Collapsed", "tinyint(1)", "boolean", "0")
// Shared channels support
sqlStore.CreateColumnIfNotExistsNoDefault("Reactions", "RemoteId", "VARCHAR(26)", "VARCHAR(26)")
sqlStore.CreateColumnIfNotExistsNoDefault("Users", "RemoteId", "VARCHAR(26)", "VARCHAR(26)")
sqlStore.CreateColumnIfNotExistsNoDefault("Posts", "RemoteId", "VARCHAR(26)", "VARCHAR(26)")
sqlStore.CreateColumnIfNotExistsNoDefault("FileInfo", "RemoteId", "VARCHAR(26)", "VARCHAR(26)")
sqlStore.CreateColumnIfNotExists("UploadSessions", "RemoteId", "VARCHAR(26)", "VARCHAR(26)", "")
sqlStore.CreateColumnIfNotExists("UploadSessions", "ReqFileId", "VARCHAR(26)", "VARCHAR(26)", "")
if _, err := sqlStore.GetMaster().ExecNoTimeout("UPDATE UploadSessions SET RemoteId='', ReqFileId='' WHERE RemoteId IS NULL"); err != nil {
mlog.Error("Error updating RemoteId,ReqFileId in UploadsSession table", mlog.Err(err))
}
uniquenessColumns := []string{"SiteUrl", "RemoteTeamId"}
if sqlStore.DriverName() == model.DatabaseDriverMysql {
uniquenessColumns = []string{"RemoteTeamId", "SiteUrl(168)"}
}
sqlStore.CreateUniqueCompositeIndexIfNotExists(RemoteClusterSiteURLUniqueIndex, "RemoteClusters", uniquenessColumns)
rootCountMigration(sqlStore)
saveSchemaVersion(sqlStore, Version5350)
}
@@ -1088,217 +818,22 @@ func upgradeDatabaseToVersion535(sqlStore *SqlStore) {
func upgradeDatabaseToVersion536(sqlStore *SqlStore) {
if shouldPerformUpgrade(sqlStore, Version5350, Version5360) {
sqlStore.CreateColumnIfNotExists("SharedChannelUsers", "ChannelId", "VARCHAR(26)", "VARCHAR(26)", "")
sqlStore.CreateColumnIfNotExists("SharedChannelRemotes", "LastPostUpdateAt", "bigint", "bigint", "0")
sqlStore.CreateColumnIfNotExists("SharedChannelRemotes", "LastPostId", "VARCHAR(26)", "VARCHAR(26)", "")
saveSchemaVersion(sqlStore, Version5360)
}
}
func rootCountMigration(sqlStore *SqlStore) {
totalMsgCountRootExists := sqlStore.DoesColumnExist("Channels", "TotalMsgCountRoot")
msgCountRootExists := sqlStore.DoesColumnExist("ChannelMembers", "MsgCountRoot")
sqlStore.CreateColumnIfNotExists("ChannelMembers", "MentionCountRoot", "bigint", "bigint", "0")
sqlStore.AlterDefaultIfColumnExists("ChannelMembers", "MentionCountRoot", model.NewString("0"), model.NewString("0"))
mentionCountRootCTE := `
SELECT ChannelId, COALESCE(SUM(UnreadMentions), 0) AS UnreadMentions, UserId
FROM ThreadMemberships
LEFT JOIN Threads ON ThreadMemberships.PostId = Threads.PostId
GROUP BY Threads.ChannelId, ThreadMemberships.UserId
`
updateMentionCountRootQuery := `
UPDATE ChannelMembers INNER JOIN (` + mentionCountRootCTE + `) AS q ON
q.ChannelId = ChannelMembers.ChannelId AND
q.UserId=ChannelMembers.UserId AND
ChannelMembers.MentionCount > 0
SET MentionCountRoot = ChannelMembers.MentionCount - q.UnreadMentions
`
if sqlStore.DriverName() == model.DatabaseDriverPostgres {
updateMentionCountRootQuery = `
WITH q AS (` + mentionCountRootCTE + `)
UPDATE channelmembers
SET MentionCountRoot = ChannelMembers.MentionCount - q.UnreadMentions
FROM q
WHERE
q.ChannelId = ChannelMembers.ChannelId AND
q.UserId = ChannelMembers.UserId AND
ChannelMembers.MentionCount > 0
`
}
if _, err := sqlStore.GetMaster().ExecNoTimeout(updateMentionCountRootQuery); err != nil {
mlog.Error("Error updating ChannelId in Threads table", mlog.Err(err))
}
sqlStore.CreateColumnIfNotExists("Channels", "TotalMsgCountRoot", "bigint", "bigint", "0")
sqlStore.CreateColumnIfNotExistsNoDefault("Channels", "LastRootAt", "bigint", "bigint")
defer sqlStore.RemoveColumnIfExists("Channels", "LastRootAt")
sqlStore.CreateColumnIfNotExists("ChannelMembers", "MsgCountRoot", "bigint", "bigint", "0")
sqlStore.AlterDefaultIfColumnExists("ChannelMembers", "MsgCountRoot", model.NewString("0"), model.NewString("0"))
forceIndex := ""
if sqlStore.DriverName() == model.DatabaseDriverMysql {
forceIndex = "FORCE INDEX(idx_posts_channel_id_update_at)"
}
totalMsgCountRootCTE := `
SELECT Channels.Id channelid, COALESCE(COUNT(*),0) newcount, COALESCE(MAX(Posts.CreateAt), 0) as lastpost
FROM Channels
LEFT JOIN Posts ` + forceIndex + ` ON Channels.Id = Posts.ChannelId
WHERE Posts.RootId = ''
GROUP BY Channels.Id
`
channelsCTE := "SELECT TotalMsgCountRoot, Id, LastRootAt from Channels"
updateChannels := `
WITH q AS (` + totalMsgCountRootCTE + `)
UPDATE Channels SET TotalMsgCountRoot = q.newcount, LastRootAt=q.lastpost
FROM q where q.channelid=Channels.Id;
`
updateChannelMembers := `
WITH q as (` + channelsCTE + `)
UPDATE ChannelMembers CM SET MsgCountRoot=TotalMsgCountRoot
FROM q WHERE q.id=CM.ChannelId AND LastViewedAt >= q.lastrootat;
`
if sqlStore.DriverName() == model.DatabaseDriverMysql {
updateChannels = `
UPDATE Channels
INNER Join (` + totalMsgCountRootCTE + `) as q
ON q.channelid=Channels.Id
SET TotalMsgCountRoot = q.newcount, LastRootAt=q.lastpost;
`
updateChannelMembers = `
UPDATE ChannelMembers CM
INNER JOIN (` + channelsCTE + `) as q
ON q.id=CM.ChannelId and LastViewedAt >= q.lastrootat
SET MsgCountRoot=TotalMsgCountRoot
`
}
if !totalMsgCountRootExists {
if _, err := sqlStore.GetMaster().ExecNoTimeout(updateChannels); err != nil {
mlog.Error("Error updating Channels table", mlog.Err(err))
}
}
if !msgCountRootExists {
if _, err := sqlStore.GetMaster().ExecNoTimeout(updateChannelMembers); err != nil {
mlog.Error("Error updating ChannelMembers table", mlog.Err(err))
}
}
}
func upgradeDatabaseToVersion537(sqlStore *SqlStore) {
if shouldPerformUpgrade(sqlStore, Version5360, Version5370) {
sqlStore.RemoveIndexIfExists("idx_posts_channel_id", "Posts")
sqlStore.RemoveIndexIfExists("idx_channels_name", "Channels")
sqlStore.RemoveIndexIfExists("idx_publicchannels_name", "PublicChannels")
sqlStore.RemoveIndexIfExists("idx_channelmembers_channel_id", "ChannelMembers")
sqlStore.RemoveIndexIfExists("idx_emoji_name", "Emoji")
sqlStore.RemoveIndexIfExists("idx_oauthaccessdata_client_id", "OAuthAccessData")
sqlStore.RemoveIndexIfExists("idx_oauthauthdata_client_id", "OAuthAuthData")
sqlStore.RemoveIndexIfExists("idx_preferences_user_id", "Preferences")
sqlStore.RemoveIndexIfExists("idx_notice_views_user_id", "ProductNoticeViewState")
sqlStore.RemoveIndexIfExists("idx_notice_views_user_notice", "ProductNoticeViewState")
sqlStore.RemoveIndexIfExists("idx_status_user_id", "Status")
sqlStore.RemoveIndexIfExists("idx_teammembers_team_id", "TeamMembers")
sqlStore.RemoveIndexIfExists("idx_teams_name", "Teams")
sqlStore.RemoveIndexIfExists("idx_user_access_tokens_token", "UserAccessTokens")
sqlStore.RemoveIndexIfExists("idx_user_terms_of_service_user_id", "UserTermsOfService")
sqlStore.RemoveIndexIfExists("idx_users_email", "Users")
sqlStore.RemoveIndexIfExists("idx_sharedchannelusers_user_id", "SharedChannelUsers")
sqlStore.RemoveIndexIfExists("IDX_RetentionPolicies_DisplayName_Id", "RetentionPolicies")
sqlStore.CreateIndexIfNotExists("IDX_RetentionPolicies_DisplayName", "RetentionPolicies", "DisplayName")
sqlStore.CreateColumnIfNotExistsNoDefault("Status", "DNDEndTime", "bigint", "bigint")
sqlStore.CreateColumnIfNotExistsNoDefault("Status", "PrevStatus", "VARCHAR(32)", "VARCHAR(32)")
saveSchemaVersion(sqlStore, Version5370)
}
}
func upgradeDatabaseToVersion538(sqlStore *SqlStore) {
if shouldPerformUpgrade(sqlStore, Version5370, Version5380) {
fixCRTChannelMembershipCounts(sqlStore)
fixCRTThreadCountsAndUnreads(sqlStore)
saveSchemaVersion(sqlStore, Version5380)
}
}
// fixCRTThreadCountsAndUnreads Marks threads as read for users where the last
// reply time of the thread is earlier than the time the user viewed the channel.
// Marking a thread means setting the mention count to zero and setting the
// last viewed at time of the the thread as the last viewed at time
// of the channel
func fixCRTThreadCountsAndUnreads(sqlStore *SqlStore) {
var system model.System
if err := sqlStore.GetMaster().SelectOne(&system, "SELECT * FROM Systems WHERE Name = 'CRTThreadCountsAndUnreadsMigrationComplete'"); err == nil {
return
}
threadMembershipsCTE := `
SELECT PostId, UserId, ChannelMembers.LastViewedAt as CM_LastViewedAt, Threads.LastReplyAt
FROM Threads
INNER JOIN ChannelMembers on ChannelMembers.ChannelId = Threads.ChannelId
WHERE Threads.LastReplyAt <= ChannelMembers.LastViewedAt
`
updateThreadMembershipQuery := `
WITH q as (` + threadMembershipsCTE + `)
UPDATE ThreadMemberships set LastViewed = q.CM_LastViewedAt + 1, UnreadMentions = 0, LastUpdated = :Now
FROM q WHERE ThreadMemberships.Postid = q.PostId AND ThreadMemberships.UserId = q.UserId
`
if sqlStore.DriverName() == model.DatabaseDriverMysql {
updateThreadMembershipQuery = `
UPDATE ThreadMemberships
INNER JOIN (` + threadMembershipsCTE + `) as q
ON ThreadMemberships.Postid = q.PostId AND ThreadMemberships.UserId = q.UserId
SET LastViewed = q.CM_LastViewedAt + 1, UnreadMentions = 0, LastUpdated = :Now
`
}
if _, err := sqlStore.GetMaster().ExecNoTimeout(updateThreadMembershipQuery, map[string]interface{}{"Now": model.GetMillis()}); err != nil {
mlog.Error("Error updating lastviewedat and unreadmentions of threadmemberships", mlog.Err(err))
return
}
if _, err := sqlStore.GetMaster().ExecNoTimeout("INSERT INTO Systems VALUES ('CRTThreadCountsAndUnreadsMigrationComplete', 'true')"); err != nil {
mlog.Error("Error marking migration as done", mlog.Err(err))
}
}
// fixCRTChannelMembershipCounts fixes the channel counts, i.e. the total message count,
// total root message count, mention count, and mention count in root messages for users
// who have viewed the channel after the last post in the channel
func fixCRTChannelMembershipCounts(sqlStore *SqlStore) {
var system model.System
if err := sqlStore.GetMaster().SelectOne(&system, "SELECT * FROM Systems WHERE Name = 'CRTChannelMembershipCountsMigrationComplete'"); err == nil {
return
}
channelMembershipsCountsAndMentions := `
UPDATE ChannelMembers
SET MentionCount=0, MentionCountRoot=0, MsgCount=Channels.TotalMsgCount, MsgCountRoot=Channels.TotalMsgCountRoot, LastUpdateAt = :Now
FROM Channels
WHERE ChannelMembers.Channelid = Channels.Id AND ChannelMembers.LastViewedAt >= Channels.LastPostAt;
`
if sqlStore.DriverName() == model.DatabaseDriverMysql {
channelMembershipsCountsAndMentions = `
UPDATE ChannelMembers
INNER JOIN Channels on Channels.Id = ChannelMembers.ChannelId
SET MentionCount=0, MentionCountRoot=0, MsgCount=Channels.TotalMsgCount, MsgCountRoot=Channels.TotalMsgCountRoot, LastUpdateAt = :Now
WHERE ChannelMembers.LastViewedAt >= Channels.LastPostAt;
`
}
if _, err := sqlStore.GetMaster().ExecNoTimeout(channelMembershipsCountsAndMentions, map[string]interface{}{"Now": model.GetMillis()}); err != nil {
mlog.Error("Error updating counts and unreads for channelmemberships", mlog.Err(err))
return
}
if _, err := sqlStore.GetMaster().ExecNoTimeout("INSERT INTO Systems VALUES ('CRTChannelMembershipCountsMigrationComplete', 'true')"); err != nil {
mlog.Error("Error marking migration as done", mlog.Err(err))
}
}
func upgradeDatabaseToVersion539(sqlStore *SqlStore) {
if shouldPerformUpgrade(sqlStore, Version5380, Version5390) {
saveSchemaVersion(sqlStore, Version5390)
@@ -1307,108 +842,12 @@ func upgradeDatabaseToVersion539(sqlStore *SqlStore) {
func upgradeDatabaseToVersion600(sqlStore *SqlStore) {
if shouldPerformUpgrade(sqlStore, Version5390, Version600) {
sqlStore.GetMaster().ExecNoTimeout("UPDATE Posts SET RootId = ParentId WHERE RootId = '' AND RootId != ParentId")
if sqlStore.DriverName() == model.DatabaseDriverMysql {
if sqlStore.DoesColumnExist("Posts", "ParentId") {
sqlStore.GetMaster().ExecNoTimeout("ALTER TABLE Posts MODIFY COLUMN FileIds text, MODIFY COLUMN Props JSON, DROP COLUMN ParentId")
} else {
sqlStore.GetMaster().ExecNoTimeout("ALTER TABLE Posts MODIFY COLUMN FileIds text, MODIFY COLUMN Props JSON")
}
} else {
sqlStore.AlterColumnTypeIfExists("Posts", "FileIds", "text", "varchar(300)")
sqlStore.AlterColumnTypeIfExists("Posts", "Props", "JSON", "jsonb")
sqlStore.RemoveColumnIfExists("Posts", "ParentId")
}
sqlStore.AlterColumnTypeIfExists("ChannelMembers", "NotifyProps", "JSON", "jsonb")
sqlStore.AlterColumnTypeIfExists("Jobs", "Data", "JSON", "jsonb")
sqlStore.AlterColumnTypeIfExists("LinkMetadata", "Data", "JSON", "jsonb")
sqlStore.AlterColumnTypeIfExists("Sessions", "Props", "JSON", "jsonb")
sqlStore.AlterColumnTypeIfExists("Threads", "Participants", "JSON", "jsonb")
sqlStore.AlterColumnTypeIfExists("Users", "Props", "JSON", "jsonb")
sqlStore.AlterColumnTypeIfExists("Users", "NotifyProps", "JSON", "jsonb")
info, err := sqlStore.GetColumnInfo("Users", "Timezone")
if err != nil {
mlog.Error("Error getting column info",
mlog.String("table", "Users"),
mlog.String("column", "Timezone"),
mlog.Err(err),
)
} else if info.DefaultValue != "" {
sqlStore.RemoveDefaultIfColumnExists("Users", "Timezone")
}
sqlStore.AlterColumnTypeIfExists("Users", "Timezone", "JSON", "jsonb")
sqlStore.GetMaster().ExecNoTimeout("UPDATE CommandWebhooks SET RootId = ParentId WHERE RootId = '' AND RootId != ParentId")
sqlStore.RemoveColumnIfExists("CommandWebhooks", "ParentId")
sqlStore.CreateCompositeIndexIfNotExists("idx_posts_root_id_delete_at", "Posts", []string{"RootId", "DeleteAt"})
sqlStore.RemoveIndexIfExists("idx_posts_root_id", "Posts")
sqlStore.CreateCompositeIndexIfNotExists("idx_channels_team_id_display_name", "Channels", []string{"TeamId", "DisplayName"})
sqlStore.CreateCompositeIndexIfNotExists("idx_channels_team_id_type", "Channels", []string{"TeamId", "Type"})
sqlStore.RemoveIndexIfExists("idx_channels_team_id", "Channels")
sqlStore.CreateCompositeIndexIfNotExists("idx_threads_channel_id_last_reply_at", "Threads", []string{"ChannelId", "LastReplyAt"})
sqlStore.RemoveIndexIfExists("idx_threads_channel_id", "Threads")
sqlStore.CreateCompositeIndexIfNotExists("idx_channelmembers_user_id_channel_id_last_viewed_at", "ChannelMembers", []string{"UserId", "ChannelId", "LastViewedAt"})
sqlStore.CreateCompositeIndexIfNotExists("idx_channelmembers_channel_id_scheme_guest_user_id", "ChannelMembers", []string{"ChannelId", "SchemeGuest", "UserId"})
sqlStore.RemoveIndexIfExists("idx_channelmembers_user_id", "ChannelMembers")
sqlStore.CreateCompositeIndexIfNotExists("idx_status_status_dndendtime", "Status", []string{"Status", "DNDEndTime"})
sqlStore.RemoveIndexIfExists("idx_status_status", "Status")
saveSchemaVersion(sqlStore, Version600)
}
}
func upgradeDatabaseToVersion610(sqlStore *SqlStore) {
if shouldPerformUpgrade(sqlStore, Version600, Version610) {
sqlStore.AlterColumnTypeIfExists("Sessions", "Roles", "text", "varchar(256)")
sqlStore.AlterColumnTypeIfExists("ChannelMembers", "Roles", "text", "varchar(256)")
sqlStore.AlterColumnTypeIfExists("TeamMembers", "Roles", "text", "varchar(256)")
sqlStore.CreateCompositeIndexIfNotExists("idx_jobs_status_type", "Jobs", []string{"Status", "Type"})
forceIndex := ""
if sqlStore.DriverName() == model.DatabaseDriverMysql {
forceIndex = "FORCE INDEX(idx_posts_channel_id_update_at)"
}
lastRootPostAtExists := sqlStore.DoesColumnExist("Channels", "LastRootPostAt")
sqlStore.CreateColumnIfNotExists("Channels", "LastRootPostAt", "bigint", "bigint", "0")
lastRootPostAtCTE := `
SELECT Channels.Id channelid, COALESCE(MAX(Posts.CreateAt), 0) as lastrootpost
FROM Channels
LEFT JOIN Posts ` + forceIndex + ` ON Channels.Id = Posts.ChannelId
WHERE Posts.RootId = ''
GROUP BY Channels.Id
`
updateChannels := `
WITH q AS (` + lastRootPostAtCTE + `)
UPDATE Channels SET LastRootPostAt=q.lastrootpost
FROM q where q.channelid=Channels.Id;
`
if sqlStore.DriverName() == model.DatabaseDriverMysql {
updateChannels = `
UPDATE Channels
INNER Join (` + lastRootPostAtCTE + `) as q
ON q.channelid=Channels.Id
SET LastRootPostAt=lastrootpost;
`
}
if !lastRootPostAtExists {
if _, err := sqlStore.GetMaster().ExecNoTimeout(updateChannels); err != nil {
mlog.Error("Error updating Channels table", mlog.Err(err))
}
}
saveSchemaVersion(sqlStore, Version610)
}
}
@@ -1421,17 +860,6 @@ func upgradeDatabaseToVersion620(sqlStore *SqlStore) {
func upgradeDatabaseToVersion630(sqlStore *SqlStore) {
if shouldPerformUpgrade(sqlStore, Version620, Version630) {
sqlStore.CreateColumnIfNotExists("Schemes", "DefaultPlaybookAdminRole", "VARCHAR(64)", "VARCHAR(64)", "")
sqlStore.CreateColumnIfNotExists("Schemes", "DefaultPlaybookMemberRole", "VARCHAR(64)", "VARCHAR(64)", "")
sqlStore.CreateColumnIfNotExists("Schemes", "DefaultRunAdminRole", "VARCHAR(64)", "VARCHAR(64)", "")
sqlStore.CreateColumnIfNotExists("Schemes", "DefaultRunMemberRole", "VARCHAR(64)", "VARCHAR(64)", "")
sqlStore.AlterColumnTypeIfExists("PluginKeyValueStore", "PKey", "VARCHAR(150)", "VARCHAR(150)")
if sqlStore.DoesColumnExist("Users", "AcceptedTermsOfServiceId") {
sqlStore.GetMaster().ExecNoTimeout("ALTER TABLE Users DROP COLUMN AcceptedTermsOfServiceId")
}
saveSchemaVersion(sqlStore, Version630)
}
}

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

@@ -4,13 +4,10 @@
package sqlstore
import (
"context"
"testing"
"github.com/stretchr/testify/assert"
"github.com/stretchr/testify/require"
"github.com/mattermost/mattermost-server/v6/model"
"github.com/mattermost/mattermost-server/v6/store"
)
@@ -116,293 +113,3 @@ func TestSaveSchemaVersion(t *testing.T) {
})
})
}
func createChannelMemberWithLastViewAt(ss store.Store, channelId, userId string, lastViewAt int64) *model.ChannelMember {
m := model.ChannelMember{}
m.ChannelId = channelId
m.UserId = userId
m.LastViewedAt = lastViewAt
m.NotifyProps = model.GetDefaultChannelNotifyProps()
cm, _ := ss.Channel().SaveMember(&m)
return cm
}
func createPostWithTimestamp(ss store.Store, channelId, userId, rootId string, timestamp int64) *model.Post {
m := model.Post{}
m.CreateAt = timestamp
m.ChannelId = channelId
m.UserId = userId
m.RootId = rootId
m.Message = "zz" + model.NewId() + "b"
p, _ := ss.Post().Save(&m)
return p
}
func createChannelWithLastPostAt(ss store.Store, teamId, creatorId string, lastPostAt, msgCount, rootCount int64) (*model.Channel, error) {
m := model.Channel{}
m.TeamId = teamId
m.TotalMsgCount = msgCount
m.TotalMsgCountRoot = rootCount
m.LastPostAt = lastPostAt
m.CreatorId = creatorId
m.DisplayName = "Name"
m.Name = "zz" + model.NewId() + "b"
m.Type = model.ChannelTypeOpen
return ss.Channel().Save(&m, -1)
}
func TestMsgCountRootMigration(t *testing.T) {
type TestCaseChannel struct {
Name string
PostTimes []int64
ReplyTimes []int64
MembershipsLastViewAt []int64
ExpectedMembershipMsgCountRoot []int64
}
type TestTableEntry struct {
name string
data []TestCaseChannel
}
testTable := []TestTableEntry{
{
name: "test1",
data: []TestCaseChannel{
{
Name: "channel with one post",
PostTimes: []int64{1000},
ReplyTimes: []int64{0},
MembershipsLastViewAt: []int64{1},
ExpectedMembershipMsgCountRoot: []int64{0},
},
{
Name: "channel with one post, read",
PostTimes: []int64{1000},
ReplyTimes: []int64{0},
MembershipsLastViewAt: []int64{1000},
ExpectedMembershipMsgCountRoot: []int64{1},
},
{
Name: "with one reply, viewed after 2nd root",
PostTimes: []int64{1000, 2000, 3000, 4000},
ReplyTimes: []int64{1001, 0, 0, 0},
MembershipsLastViewAt: []int64{2001},
ExpectedMembershipMsgCountRoot: []int64{0},
},
{
Name: "two replies, 3 memberships",
PostTimes: []int64{1000, 2000, 3000},
ReplyTimes: []int64{1001, 2001, 0},
MembershipsLastViewAt: []int64{2000, 5000, 0},
ExpectedMembershipMsgCountRoot: []int64{0, 3, 0},
},
},
},
}
for _, testCase := range testTable {
t.Run(testCase.name, func(t *testing.T) {
StoreTest(t, func(t *testing.T, ss store.Store) {
sqlStore := ss.(*SqlStore)
team := createTeam(ss)
for _, testChannel := range testCase.data {
t.Run(testChannel.Name, func(t *testing.T) {
lastPostAt := int64(0)
for i := range testChannel.PostTimes {
if testChannel.PostTimes[i] > lastPostAt {
lastPostAt = testChannel.PostTimes[i]
}
if testChannel.ReplyTimes[i] > lastPostAt {
lastPostAt = testChannel.ReplyTimes[i]
}
}
channel, err := createChannelWithLastPostAt(ss, team.Id, model.NewId(), lastPostAt, int64(len(testChannel.PostTimes)+len(testChannel.ReplyTimes)), int64(len(testChannel.PostTimes)))
require.NoError(t, err)
var userIds []string
for _, md := range testChannel.MembershipsLastViewAt {
user := createUser(ss)
userIds = append(userIds, user.Id)
require.NotNil(t, user)
cm := createChannelMemberWithLastViewAt(ss, channel.Id, user.Id, md)
require.NotNil(t, cm)
}
for i, pt := range testChannel.PostTimes {
rt := testChannel.ReplyTimes[i]
post := createPostWithTimestamp(ss, channel.Id, model.NewId(), "", pt)
require.NotNil(t, post)
if rt > 0 {
reply := createPostWithTimestamp(ss, channel.Id, model.NewId(), post.Id, rt)
require.NotNil(t, reply)
}
}
_, err = sqlStore.GetMaster().Exec(`ALTER TABLE Channels DROP COLUMN TotalMsgCountRoot`)
require.NoError(t, err)
_, err = sqlStore.GetMaster().Exec(`ALTER TABLE ChannelMembers DROP COLUMN MsgCountRoot`)
require.NoError(t, err)
rootCountMigration(sqlStore)
members, err := ss.Channel().GetMembersByIds(channel.Id, userIds)
require.NoError(t, err)
for _, m := range members {
for i, uid := range userIds {
if m.UserId == uid {
assert.Equal(t, testChannel.ExpectedMembershipMsgCountRoot[i], m.MsgCountRoot)
break
}
}
}
})
}
})
})
}
}
func TestFixCRTCountsAndUnreads(t *testing.T) {
StoreTest(t, func(t *testing.T, ss store.Store) {
sqlStore := ss.(*SqlStore)
team := createTeam(ss)
uId1 := model.NewId()
uId2 := model.NewId()
c1, err := createChannelWithLastPostAt(ss, team.Id, uId1, 0, 0, 0)
require.NoError(t, err)
createChannelMemberWithLastViewAt(ss, c1.Id, uId1, 0)
createChannelMemberWithLastViewAt(ss, c1.Id, uId2, 0)
// Create a thread
// user2: root post 1
// - user1: reply 1 to root post 1
// - user2: reply 2 to root post 1
// - user1: reply 3 to root post 1
// - user2: reply 4 to root post 1
rootPost1 := createPostWithTimestamp(ss, c1.Id, uId2, "", 1)
lastReplyAt := int64(40)
_ = createPostWithTimestamp(ss, c1.Id, uId1, rootPost1.Id, 10)
_ = createPostWithTimestamp(ss, c1.Id, uId2, rootPost1.Id, 20)
_ = createPostWithTimestamp(ss, c1.Id, uId1, rootPost1.Id, 30)
_ = createPostWithTimestamp(ss, c1.Id, uId2, rootPost1.Id, lastReplyAt)
// Check created thread is good
goodThread1, err := ss.Thread().Get(rootPost1.Id)
require.NoError(t, err)
require.EqualValues(t, 4, goodThread1.ReplyCount)
require.EqualValues(t, lastReplyAt, goodThread1.LastReplyAt)
require.ElementsMatch(t, model.StringArray{uId1, uId2}, goodThread1.Participants)
// Create ThreadMembership
goodThreadMembership1, err := ss.Thread().SaveMembership(&model.ThreadMembership{
PostId: rootPost1.Id,
UserId: uId1,
Following: true,
LastViewed: lastReplyAt + 1,
LastUpdated: lastReplyAt + 1,
UnreadMentions: 0,
})
require.NoError(t, err)
goodThreadMembership2, err := ss.Thread().SaveMembership(&model.ThreadMembership{
PostId: rootPost1.Id,
UserId: uId2,
Following: true,
LastViewed: lastReplyAt + 1,
LastUpdated: lastReplyAt + 1,
UnreadMentions: 0,
})
require.NoError(t, err)
// Update channel last viewed at
// set channel as fully read for user1
_, err = ss.Channel().UpdateLastViewedAt([]string{c1.Id}, uId1, true)
require.NoError(t, err)
// for user2 set channel as read before the last post in thread
// user2's threadmembership wont change
cm2, err := ss.Channel().GetMember(context.Background(), c1.Id, uId2)
require.NoError(t, err)
cm2.LastViewedAt = lastReplyAt - 10
_, err = ss.Channel().UpdateMember(cm2)
require.NoError(t, err)
// Update ThreadMembership with bad data, as we might expect because
// of previous bugs or changed behaviour
badThreadMembership1 := *goodThreadMembership1
badThreadMembership1.LastViewed = 30
badThreadMembership1.UnreadMentions = 4
_, err = ss.Thread().UpdateMembership(&badThreadMembership1)
require.NoError(t, err)
// Run migration to fix threads and memberships
ss.System().PermanentDeleteByName("CRTThreadCountsAndUnreadsMigrationComplete")
fixCRTThreadCountsAndUnreads(sqlStore)
// Check bad threadMemberships is fixed
fixedThreadMembership1, err := ss.Thread().GetMembershipForUser(uId1, rootPost1.Id)
require.NoError(t, err)
require.EqualValues(t, lastReplyAt+1, fixedThreadMembership1.LastViewed)
require.EqualValues(t, int64(0), fixedThreadMembership1.UnreadMentions)
require.NotEqual(t, goodThreadMembership1.LastUpdated, fixedThreadMembership1.LastUpdated)
// check good threadMembership is unchanged
fixedThreadMembership2, err := ss.Thread().GetMembershipForUser(uId2, rootPost1.Id)
require.NoError(t, err)
require.Equal(t, goodThreadMembership2, fixedThreadMembership2)
})
}
func TestFixCRTChannelUnreads(t *testing.T) {
StoreTest(t, func(t *testing.T, ss store.Store) {
sqlStore := ss.(*SqlStore)
team := createTeam(ss)
uId1 := model.NewId()
uId2 := model.NewId()
channelLastPostAt := int64(100)
channelMsgCount := int64(200)
channelMsgCountRoot := int64(100)
c1, err := createChannelWithLastPostAt(ss, team.Id, uId1, channelLastPostAt, channelMsgCount, channelMsgCountRoot)
require.NoError(t, err)
// Make a membership entry
cm1, err := ss.Channel().SaveMember(&model.ChannelMember{
ChannelId: c1.Id,
UserId: uId1,
LastViewedAt: channelLastPostAt - 50,
NotifyProps: model.GetDefaultChannelNotifyProps(),
MsgCount: 80,
MsgCountRoot: 40,
MentionCount: 5,
MentionCountRoot: 5,
})
require.NoError(t, err)
// make a bad membership entry
// LastViewed at newer than channel LastPostAt and with unreads and mentions
cm2, err := ss.Channel().SaveMember(&model.ChannelMember{
ChannelId: c1.Id,
UserId: uId2,
LastViewedAt: channelLastPostAt + 50,
NotifyProps: model.GetDefaultChannelNotifyProps(),
MsgCount: 80,
MsgCountRoot: 40,
MentionCount: 5,
MentionCountRoot: 5,
})
require.NoError(t, err)
ss.System().PermanentDeleteByName("CRTChannelMembershipCountsMigrationComplete")
fixCRTChannelMembershipCounts(sqlStore)
cm1AfterFix, err := ss.Channel().GetMember(context.Background(), c1.Id, uId1)
require.NoError(t, err)
// Migration should not affect this channelmembership
require.Equal(t, *cm1, *cm1AfterFix)
cm2AfterFix, err := ss.Channel().GetMember(context.Background(), c1.Id, uId2)
require.NoError(t, err)
// Check that the channelmembership is fixed
require.NotEqual(t, *cm2, *cm2AfterFix)
require.EqualValues(t, 0, cm2AfterFix.MentionCount)
require.EqualValues(t, 0, cm2AfterFix.MentionCountRoot)
require.Equal(t, channelMsgCount, cm2AfterFix.MsgCount)
require.Equal(t, channelMsgCountRoot, cm2AfterFix.MsgCountRoot)
require.NotEqual(t, cm2.LastUpdateAt, cm2AfterFix.LastUpdateAt)
})
}

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

@@ -35,12 +35,6 @@ func newSqlUploadSessionStore(sqlStore *SqlStore) store.UploadSessionStore {
return s
}
func (us SqlUploadSessionStore) createIndexesIfNotExists() {
us.CreateIndexIfNotExists("idx_uploadsessions_user_id", "UploadSessions", "Type")
us.CreateIndexIfNotExists("idx_uploadsessions_create_at", "UploadSessions", "CreateAt")
us.CreateIndexIfNotExists("idx_uploadsessions_user_id", "UploadSessions", "UserId")
}
func (us SqlUploadSessionStore) Save(session *model.UploadSession) (*model.UploadSession, error) {
if session == nil {
return nil, errors.New("SqlUploadSessionStore.Save: session should not be nil")

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

@@ -31,10 +31,6 @@ func newSqlUserAccessTokenStore(sqlStore *SqlStore) store.UserAccessTokenStore {
return s
}
func (s SqlUserAccessTokenStore) createIndexesIfNotExists() {
s.CreateIndexIfNotExists("idx_user_access_tokens_user_id", "UserAccessTokens", "UserId")
}
func (s SqlUserAccessTokenStore) Save(token *model.UserAccessToken) (*model.UserAccessToken, error) {
token.PreSave()

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

@@ -81,25 +81,6 @@ func newSqlUserStore(sqlStore *SqlStore, metrics einterfaces.MetricsInterface) s
return us
}
func (us SqlUserStore) createIndexesIfNotExists() {
us.CreateIndexIfNotExists("idx_users_update_at", "Users", "UpdateAt")
us.CreateIndexIfNotExists("idx_users_create_at", "Users", "CreateAt")
us.CreateIndexIfNotExists("idx_users_delete_at", "Users", "DeleteAt")
if us.DriverName() == model.DatabaseDriverPostgres {
us.CreateIndexIfNotExists("idx_users_email_lower_textpattern", "Users", "lower(Email) text_pattern_ops")
us.CreateIndexIfNotExists("idx_users_username_lower_textpattern", "Users", "lower(Username) text_pattern_ops")
us.CreateIndexIfNotExists("idx_users_nickname_lower_textpattern", "Users", "lower(Nickname) text_pattern_ops")
us.CreateIndexIfNotExists("idx_users_firstname_lower_textpattern", "Users", "lower(FirstName) text_pattern_ops")
us.CreateIndexIfNotExists("idx_users_lastname_lower_textpattern", "Users", "lower(LastName) text_pattern_ops")
}
us.CreateFullTextIndexIfNotExists("idx_users_all_txt", "Users", strings.Join(UserSearchTypeAll, ", "))
us.CreateFullTextIndexIfNotExists("idx_users_all_no_full_name_txt", "Users", strings.Join(UserSearchTypeAllNoFullName, ", "))
us.CreateFullTextIndexIfNotExists("idx_users_names_txt", "Users", strings.Join(UserSearchTypeNames, ", "))
us.CreateFullTextIndexIfNotExists("idx_users_names_no_full_name_txt", "Users", strings.Join(UserSearchTypeNamesNoFullName, ", "))
}
func (us SqlUserStore) Save(user *model.User) (*model.User, error) {
if user.Id != "" && !user.IsRemote() {
return nil, store.NewErrInvalidInput("User", "id", user.Id)

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

@@ -58,25 +58,10 @@ func newSqlWebhookStore(sqlStore *SqlStore, metrics einterfaces.MetricsInterface
return s
}
func (s SqlWebhookStore) createIndexesIfNotExists() {
s.CreateIndexIfNotExists("idx_incoming_webhook_user_id", "IncomingWebhooks", "UserId")
s.CreateIndexIfNotExists("idx_incoming_webhook_team_id", "IncomingWebhooks", "TeamId")
s.CreateIndexIfNotExists("idx_outgoing_webhook_team_id", "OutgoingWebhooks", "TeamId")
s.CreateIndexIfNotExists("idx_incoming_webhook_update_at", "IncomingWebhooks", "UpdateAt")
s.CreateIndexIfNotExists("idx_incoming_webhook_create_at", "IncomingWebhooks", "CreateAt")
s.CreateIndexIfNotExists("idx_incoming_webhook_delete_at", "IncomingWebhooks", "DeleteAt")
s.CreateIndexIfNotExists("idx_outgoing_webhook_update_at", "OutgoingWebhooks", "UpdateAt")
s.CreateIndexIfNotExists("idx_outgoing_webhook_create_at", "OutgoingWebhooks", "CreateAt")
s.CreateIndexIfNotExists("idx_outgoing_webhook_delete_at", "OutgoingWebhooks", "DeleteAt")
}
func (s SqlWebhookStore) InvalidateWebhookCache(webhookId string) {
}
func (s SqlWebhookStore) SaveIncoming(webhook *model.IncomingWebhook) (*model.IncomingWebhook, error) {
if webhook.Id != "" {
return nil, store.NewErrInvalidInput("IncomingWebhook", "id", webhook.Id)
}