[MM-36995] Start using db native JSON datatypes (#17930)

* Start using db native JSON datatypes

* Fix syntax to work on MySQL 5.7.12
Этот коммит содержится в:
Claudio Costa
2021-07-28 08:50:36 +02:00
коммит произвёл GitHub
родитель 1c63e6a848
Коммит 1ae1c38c9f
15 изменённых файлов: 84 добавлений и 54 удалений

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

@@ -391,7 +391,7 @@ func newSqlChannelStore(sqlStore *SqlStore, metrics einterfaces.MetricsInterface
tablem.ColMap("ChannelId").SetMaxSize(26)
tablem.ColMap("UserId").SetMaxSize(26)
tablem.ColMap("Roles").SetMaxSize(64)
tablem.ColMap("NotifyProps").SetMaxSize(2000)
tablem.ColMap("NotifyProps").SetDataType(sqlStore.jsonDataType())
tablePublicChannels := db.AddTableWithName(publicChannel{}, "PublicChannels").SetKeys(false, "Id")
tablePublicChannels.ColMap("Id").SetMaxSize(26)
@@ -1898,45 +1898,27 @@ func (s SqlChannelStore) GetMemberCountsByGroup(ctx context.Context, channelID s
selectStr := "GroupMembers.GroupId, COUNT(ChannelMembers.UserId) AS ChannelMemberCount"
if includeTimezones {
// Length of default timezone (len {"automaticTimezone":"","manualTimezone":"","useAutomaticTimezone":"true"})
defaultTimezoneLength := `74`
// Beginning and end of the value for the automatic and manual timezones respectively
autoTimezone := `LOCATE(':', Users.Timezone) + 2`
autoTimezoneEnd := `LOCATE(',', Users.Timezone) - LOCATE(':', Users.Timezone) - 3`
manualTimezone := `LOCATE(',', Users.Timezone) + 19`
manualTimezoneEnd := `LOCATE('useAutomaticTimezone', Users.Timezone) - 22 - LOCATE(',', Users.Timezone)`
if s.DriverName() == model.DatabaseDriverPostgres {
autoTimezone = `POSITION(':' IN Users.Timezone) + 2`
autoTimezoneEnd = `POSITION(',' IN Users.Timezone) - POSITION(':' IN Users.Timezone) - 3`
manualTimezone = `POSITION(',' IN Users.Timezone) + 19`
manualTimezoneEnd = `POSITION('useAutomaticTimezone' IN Users.Timezone) - 22 - POSITION(',' IN Users.Timezone)`
}
selectStr = `
GroupMembers.GroupId,
COUNT(ChannelMembers.UserId) AS ChannelMemberCount,
COUNT(DISTINCT
if s.DriverName() == model.DatabaseDriverMysql {
selectStr += `,
COUNT(DISTINCT
(
CASE WHEN Timezone like '%"useAutomaticTimezone":"true"}' AND LENGTH(Timezone) > ` + defaultTimezoneLength + `
THEN
SUBSTRING(
Timezone
FROM ` + autoTimezone + `
FOR ` + autoTimezoneEnd + `
)
WHEN Timezone like '%"useAutomaticTimezone":"false"}' AND LENGTH(Timezone) > ` + defaultTimezoneLength + `
THEN
SUBSTRING(
Timezone
FROM ` + manualTimezone + `
FOR ` + manualTimezoneEnd + `
)
CASE WHEN Timezone->"$.useAutomaticTimezone" = 'true' AND LENGTH(JSON_UNQUOTE(Timezone->"$.automaticTimezone")) > 0
THEN Timezone->"$.automaticTimezone"
WHEN Timezone->"$.useAutomaticTimezone" = 'false' AND LENGTH(JSON_UNQUOTE(Timezone->"$.manualTimezone")) > 0
THEN Timezone->"$.manualTimezone"
END
)
) AS ChannelMemberTimezonesCount
`
)) AS ChannelMemberTimezonesCount`
} else if s.DriverName() == model.DatabaseDriverPostgres {
selectStr += `,
COUNT(DISTINCT
(
CASE WHEN Timezone->>'useAutomaticTimezone' = 'true' AND length(Timezone->>'automaticTimezone') > 0
THEN Timezone->>'automaticTimezone'
WHEN Timezone->>'useAutomaticTimezone' = 'false' AND length(Timezone->>'manualTimezone') > 0
THEN Timezone->>'manualTimezone'
END
)) AS ChannelMemberTimezonesCount`
}
}
query := s.getQueryBuilder().
@@ -1954,6 +1936,7 @@ func (s SqlChannelStore) GetMemberCountsByGroup(ctx context.Context, channelID s
if err != nil {
return nil, errors.Wrap(err, "channel_tosql")
}
var data []*model.ChannelMemberCountByGroup
if _, err = s.DBFromContext(ctx).Select(&data, queryString, args...); err != nil {
return nil, errors.Wrapf(err, "failed to count ChannelMembers with channelId=%s", channelID)

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

@@ -28,7 +28,7 @@ func newSqlJobStore(sqlStore *SqlStore) store.JobStore {
table.ColMap("Id").SetMaxSize(26)
table.ColMap("Type").SetMaxSize(32)
table.ColMap("Status").SetMaxSize(32)
table.ColMap("Data").SetMaxSize(1024)
table.ColMap("Data").SetDataType(sqlStore.jsonDataType())
}
return s

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

@@ -24,7 +24,7 @@ func newSqlLinkMetadataStore(sqlStore *SqlStore) store.LinkMetadataStore {
table := db.AddTableWithName(model.LinkMetadata{}, "LinkMetadata").SetKeys(false, "Hash")
table.ColMap("URL").SetMaxSize(2048)
table.ColMap("Type").SetMaxSize(16)
table.ColMap("Data").SetMaxSize(4096)
table.ColMap("Data").SetDataType(sqlStore.jsonDataType())
}
return s

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

@@ -146,7 +146,7 @@ func newSqlPostStore(sqlStore *SqlStore, metrics einterfaces.MetricsInterface) s
table.ColMap("Message").SetMaxSize(model.PostMessageMaxBytesV2)
table.ColMap("Type").SetMaxSize(26)
table.ColMap("Hashtags").SetMaxSize(1000)
table.ColMap("Props").SetMaxSize(8000)
table.ColMap("Props").SetDataType(sqlStore.jsonDataType())
table.ColMap("Filenames").SetMaxSize(model.PostFilenamesMaxRunes)
table.ColMap("FileIds").SetMaxSize(300)
table.ColMap("RemoteId").SetMaxSize(26)

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

@@ -34,7 +34,7 @@ func newSqlSessionStore(sqlStore *SqlStore) store.SessionStore {
table.ColMap("UserId").SetMaxSize(26)
table.ColMap("DeviceId").SetMaxSize(512)
table.ColMap("Roles").SetMaxSize(64)
table.ColMap("Props").SetMaxSize(1000)
table.ColMap("Props").SetDataType(sqlStore.jsonDataType())
}
return us

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

@@ -911,7 +911,12 @@ func (ss *SqlStore) AlterColumnTypeIfExists(tableName string, columnName string,
if ss.DriverName() == model.DatabaseDriverMysql {
_, err = ss.GetMaster().ExecNoTimeout("ALTER TABLE " + tableName + " MODIFY " + columnName + " " + mySqlColType)
} else if ss.DriverName() == model.DatabaseDriverPostgres {
_, err = ss.GetMaster().ExecNoTimeout("ALTER TABLE " + strings.ToLower(tableName) + " ALTER COLUMN " + strings.ToLower(columnName) + " TYPE " + postgresColType)
query := "ALTER TABLE " + strings.ToLower(tableName) + " ALTER COLUMN " + strings.ToLower(columnName) + " TYPE " + postgresColType
// We need to explicitly cast when moving from text based to jsonb datatypes.
if postgresColType == "jsonb" {
query += " USING " + strings.ToLower(columnName) + "::jsonb"
}
_, err = ss.GetMaster().ExecNoTimeout(query)
}
if err != nil {
@@ -1742,3 +1747,10 @@ func versionString(v int, driver string) string {
}
return ""
}
func (ss *SqlStore) jsonDataType() string {
if ss.DriverName() == model.DatabaseDriverPostgres {
return "jsonb"
}
return "json"
}

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

@@ -33,7 +33,7 @@ func newSqlThreadStore(sqlStore *SqlStore) store.ThreadStore {
tableThreads := db.AddTableWithName(model.Thread{}, "Threads").SetKeys(false, "PostId")
tableThreads.ColMap("PostId").SetMaxSize(26)
tableThreads.ColMap("ChannelId").SetMaxSize(26)
tableThreads.ColMap("Participants").SetMaxSize(0)
tableThreads.ColMap("Participants").SetDataType(sqlStore.jsonDataType())
tableThreadMemberships := db.AddTableWithName(model.ThreadMembership{}, "ThreadMemberships").SetKeys(false, "PostId", "UserId")
tableThreadMemberships.ColMap("PostId").SetMaxSize(26)
tableThreadMemberships.ColMap("UserId").SetMaxSize(26)

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

@@ -212,6 +212,7 @@ func upgradeDatabase(sqlStore *SqlStore, currentModelVersionString string) error
upgradeDatabaseToVersion536(sqlStore)
upgradeDatabaseToVersion537(sqlStore)
upgradeDatabaseToVersion538(sqlStore)
upgradeDatabaseToVersion600(sqlStore)
return nil
}
@@ -1297,3 +1298,20 @@ func fixCRTChannelMembershipCounts(sqlStore *SqlStore) {
mlog.Error("Error marking migration as done", mlog.Err(err))
}
}
func upgradeDatabaseToVersion600(sqlStore *SqlStore) {
// if shouldPerformUpgrade(sqlStore, Version5380, Version600) {
sqlStore.AlterColumnTypeIfExists("ChannelMembers", "NotifyProps", "JSON", "jsonb")
sqlStore.AlterColumnTypeIfExists("Jobs", "Data", "JSON", "jsonb")
sqlStore.AlterColumnTypeIfExists("LinkMetadata", "Data", "JSON", "jsonb")
sqlStore.AlterColumnTypeIfExists("Posts", "Props", "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")
sqlStore.AlterColumnTypeIfExists("Users", "Timezone", "JSON", "jsonb")
// saveSchemaVersion(sqlStore, Version600)
// }
}

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

@@ -69,13 +69,13 @@ func newSqlUserStore(sqlStore *SqlStore, metrics einterfaces.MetricsInterface) s
table.ColMap("FirstName").SetMaxSize(64)
table.ColMap("LastName").SetMaxSize(64)
table.ColMap("Roles").SetMaxSize(256)
table.ColMap("Props").SetMaxSize(4000)
table.ColMap("NotifyProps").SetMaxSize(2000)
table.ColMap("Props").SetDataType(sqlStore.jsonDataType())
table.ColMap("NotifyProps").SetDataType(sqlStore.jsonDataType())
table.ColMap("Locale").SetMaxSize(5)
table.ColMap("MfaSecret").SetMaxSize(128)
table.ColMap("RemoteId").SetMaxSize(26)
table.ColMap("Position").SetMaxSize(128)
table.ColMap("Timezone").SetMaxSize(256)
table.ColMap("Timezone").SetDataType(sqlStore.jsonDataType())
}
return us