|
@@ -24,7 +24,7 @@ const (
|
24
|
24
|
// 'version' of the database schema
|
25
|
25
|
keySchemaVersion = "db.version"
|
26
|
26
|
// latest schema of the db
|
27
|
|
- latestDbSchema = 18
|
|
27
|
+ latestDbSchema = 19
|
28
|
28
|
|
29
|
29
|
keyCloakSecret = "crypto.cloak_secret"
|
30
|
30
|
)
|
|
@@ -903,6 +903,66 @@ func schemaChangeV17ToV18(config *Config, tx *buntdb.Tx) error {
|
903
|
903
|
return nil
|
904
|
904
|
}
|
905
|
905
|
|
|
906
|
+// #1345: persist the channel-user modes of always-on clients
|
|
907
|
+func schemaChangeV18To19(config *Config, tx *buntdb.Tx) error {
|
|
908
|
+ channelToAmodesCache := make(map[string]map[string]modes.Mode)
|
|
909
|
+ joinedto := "account.joinedto "
|
|
910
|
+ var accounts []string
|
|
911
|
+ var channels [][]string
|
|
912
|
+ tx.AscendGreaterOrEqual("", joinedto, func(key, value string) bool {
|
|
913
|
+ if !strings.HasPrefix(key, joinedto) {
|
|
914
|
+ return false
|
|
915
|
+ }
|
|
916
|
+ accounts = append(accounts, strings.TrimPrefix(key, joinedto))
|
|
917
|
+ var ch []string
|
|
918
|
+ if value != "" {
|
|
919
|
+ ch = strings.Split(value, ",")
|
|
920
|
+ }
|
|
921
|
+ channels = append(channels, ch)
|
|
922
|
+ return true
|
|
923
|
+ })
|
|
924
|
+
|
|
925
|
+ for i := 0; i < len(accounts); i++ {
|
|
926
|
+ account := accounts[i]
|
|
927
|
+ channels := channels[i]
|
|
928
|
+ tx.Delete(joinedto + account)
|
|
929
|
+ newValue := make(map[string]string, len(channels))
|
|
930
|
+ for _, channel := range channels {
|
|
931
|
+ chcfname, err := CasefoldChannel(channel)
|
|
932
|
+ if err != nil {
|
|
933
|
+ continue
|
|
934
|
+ }
|
|
935
|
+ // get amodes from the channelToAmodesCache, fill if necessary
|
|
936
|
+ amodes, ok := channelToAmodesCache[chcfname]
|
|
937
|
+ if !ok {
|
|
938
|
+ amodeStr, _ := tx.Get("channel.accounttoumode " + chcfname)
|
|
939
|
+ if amodeStr != "" {
|
|
940
|
+ jErr := json.Unmarshal([]byte(amodeStr), &amodes)
|
|
941
|
+ if jErr != nil {
|
|
942
|
+ log.Printf("error retrieving amodes for %s: %v\n", channel, jErr)
|
|
943
|
+ amodes = nil
|
|
944
|
+ }
|
|
945
|
+ }
|
|
946
|
+ // setting/using the nil value here is ok
|
|
947
|
+ channelToAmodesCache[chcfname] = amodes
|
|
948
|
+ }
|
|
949
|
+ if mode, ok := amodes[account]; ok {
|
|
950
|
+ newValue[channel] = string(mode)
|
|
951
|
+ } else {
|
|
952
|
+ newValue[channel] = ""
|
|
953
|
+ }
|
|
954
|
+ }
|
|
955
|
+ newValueBytes, jErr := json.Marshal(newValue)
|
|
956
|
+ if jErr != nil {
|
|
957
|
+ log.Printf("couldn't serialize new mode values for v19: %v\n", jErr)
|
|
958
|
+ continue
|
|
959
|
+ }
|
|
960
|
+ tx.Set("account.channeltomodes "+account, string(newValueBytes), nil)
|
|
961
|
+ }
|
|
962
|
+
|
|
963
|
+ return nil
|
|
964
|
+}
|
|
965
|
+
|
906
|
966
|
func getSchemaChange(initialVersion int) (result SchemaChange, ok bool) {
|
907
|
967
|
for _, change := range allChanges {
|
908
|
968
|
if initialVersion == change.InitialVersion {
|
|
@@ -998,4 +1058,9 @@ var allChanges = []SchemaChange{
|
998
|
1058
|
TargetVersion: 18,
|
999
|
1059
|
Changer: schemaChangeV17ToV18,
|
1000
|
1060
|
},
|
|
1061
|
+ {
|
|
1062
|
+ InitialVersion: 18,
|
|
1063
|
+ TargetVersion: 19,
|
|
1064
|
+ Changer: schemaChangeV18To19,
|
|
1065
|
+ },
|
1001
|
1066
|
}
|