Skip to content

Commit b704948

Browse files
authored
Migration attribute data to credential (#584)
* cherry-pick * chore: protocol * chore: user register and update * chore: credential * fix: cherry-pick * chore: user register and update * feat: register pb * fix: cherry-pick * feat: login * feat: check param * fix: check param * fix: protocol * fix: cherry-pick * fix: cherry-pick * fix: old data in attribute to credential * fix: old data in attribute to credential
1 parent 7f02912 commit b704948

File tree

3 files changed

+204
-0
lines changed

3 files changed

+204
-0
lines changed

start-config.yml

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -5,4 +5,5 @@ serviceBinaries:
55
admin-rpc: 1
66
toolBinaries:
77
- check-component
8+
- attribute-to-credential
89
maxFileDescriptors: 10000
Lines changed: 153 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,153 @@
1+
package main
2+
3+
import (
4+
"context"
5+
"flag"
6+
"fmt"
7+
"github.com/openimsdk/chat/internal/rpc/chat"
8+
"github.com/openimsdk/chat/pkg/common/cmd"
9+
"github.com/openimsdk/chat/pkg/common/config"
10+
"github.com/openimsdk/chat/pkg/common/constant"
11+
table "github.com/openimsdk/chat/pkg/common/db/table/chat"
12+
"github.com/openimsdk/chat/tools/dataversion"
13+
"github.com/openimsdk/protocol/sdkws"
14+
"github.com/openimsdk/tools/db/mongoutil"
15+
"github.com/openimsdk/tools/system/program"
16+
"go.mongodb.org/mongo-driver/bson"
17+
"go.mongodb.org/mongo-driver/mongo"
18+
"go.mongodb.org/mongo-driver/mongo/options"
19+
"path/filepath"
20+
)
21+
22+
const (
23+
credentialKey = "credential"
24+
credentialVersion = 1
25+
26+
attributeCollection = "attribute"
27+
credentialCollection = "credential"
28+
pageNum = 1000
29+
)
30+
31+
func initConfig(configDir string) (*config.Mongo, error) {
32+
var (
33+
mongoConfig = &config.Mongo{}
34+
)
35+
err := config.LoadConfig(filepath.Join(configDir, cmd.MongodbConfigFileName), cmd.ConfigEnvPrefixMap[cmd.MongodbConfigFileName], mongoConfig)
36+
if err != nil {
37+
return nil, err
38+
}
39+
40+
return mongoConfig, nil
41+
}
42+
43+
func pageGetAttribute(ctx context.Context, coll *mongo.Collection, pagination *sdkws.RequestPagination) (int64, []*table.Attribute, error) {
44+
return mongoutil.FindPage[*table.Attribute](ctx, coll, bson.M{}, pagination)
45+
}
46+
47+
func doAttributeToCredential() error {
48+
var index int
49+
var configDir string
50+
flag.IntVar(&index, "i", 0, "Index number")
51+
defaultConfigDir := filepath.Join("..", "..", "..", "..", "..", "config")
52+
flag.StringVar(&configDir, "c", defaultConfigDir, "Configuration dir")
53+
flag.Parse()
54+
55+
fmt.Printf("Index: %d, Config Path: %s\n", index, configDir)
56+
57+
mongoConfig, err := initConfig(configDir)
58+
if err != nil {
59+
return err
60+
}
61+
62+
ctx := context.Background()
63+
64+
mgocli, err := mongoutil.NewMongoDB(ctx, mongoConfig.Build())
65+
if err != nil {
66+
return err
67+
}
68+
69+
versionColl := mgocli.GetDB().Collection(dataversion.Collection)
70+
converted, err := dataversion.CheckVersion(versionColl, credentialKey, credentialVersion)
71+
if err != nil {
72+
return err
73+
}
74+
if converted {
75+
fmt.Println("[credential] credential data has been converted")
76+
return nil
77+
}
78+
79+
attrColl := mgocli.GetDB().Collection(attributeCollection)
80+
credColl := mgocli.GetDB().Collection(credentialCollection)
81+
82+
pagination := &sdkws.RequestPagination{
83+
PageNumber: 1,
84+
ShowNumber: pageNum,
85+
}
86+
tx := mgocli.GetTx()
87+
if err = tx.Transaction(ctx, func(ctx context.Context) error {
88+
for {
89+
total, attrs, err := pageGetAttribute(ctx, attrColl, pagination)
90+
if err != nil {
91+
return err
92+
}
93+
credentials := make([]*table.Credential, 0, pageNum*3)
94+
for _, attr := range attrs {
95+
if attr.Email != "" {
96+
credentials = append(credentials, &table.Credential{
97+
UserID: attr.UserID,
98+
Account: attr.Email,
99+
Type: constant.CredentialEmail,
100+
AllowChange: true,
101+
})
102+
}
103+
if attr.Account != "" {
104+
credentials = append(credentials, &table.Credential{
105+
UserID: attr.UserID,
106+
Account: attr.Account,
107+
Type: constant.CredentialAccount,
108+
AllowChange: true,
109+
})
110+
}
111+
if attr.PhoneNumber != "" && attr.AreaCode != "" {
112+
credentials = append(credentials, &table.Credential{
113+
UserID: attr.UserID,
114+
Account: chat.BuildCredentialPhone(attr.AreaCode, attr.PhoneNumber),
115+
Type: constant.CredentialPhone,
116+
AllowChange: true,
117+
})
118+
}
119+
120+
}
121+
for _, credential := range credentials {
122+
err = mongoutil.UpdateOne(ctx, credColl, bson.M{
123+
"user_id": credential.UserID,
124+
"type": credential.Type,
125+
}, bson.M{
126+
"$set": credential,
127+
}, false, options.Update().SetUpsert(true))
128+
if err != nil {
129+
return err
130+
}
131+
}
132+
133+
pagination.PageNumber++
134+
if total < pageNum {
135+
break
136+
}
137+
}
138+
return nil
139+
}); err != nil {
140+
return err
141+
}
142+
if err := dataversion.SetVersion(versionColl, credentialKey, credentialVersion); err != nil {
143+
return fmt.Errorf("set mongodb credential version %w", err)
144+
}
145+
fmt.Println("[credential] update old data to credential success")
146+
return nil
147+
}
148+
149+
func main() {
150+
if err := doAttributeToCredential(); err != nil {
151+
program.ExitWithError(err)
152+
}
153+
}

tools/dataversion/data_version.go

Lines changed: 50 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,50 @@
1+
package dataversion
2+
3+
import (
4+
"context"
5+
"errors"
6+
"fmt"
7+
"github.com/openimsdk/tools/db/mongoutil"
8+
"go.mongodb.org/mongo-driver/bson"
9+
"go.mongodb.org/mongo-driver/mongo"
10+
"go.mongodb.org/mongo-driver/mongo/options"
11+
"strconv"
12+
"time"
13+
)
14+
15+
const (
16+
Collection = "data_version"
17+
)
18+
19+
func CheckVersion(coll *mongo.Collection, key string, currentVersion int) (converted bool, err error) {
20+
type VersionTable struct {
21+
Key string `bson:"key"`
22+
Value string `bson:"value"`
23+
}
24+
ctx, cancel := context.WithTimeout(context.Background(), time.Second*5)
25+
defer cancel()
26+
res, err := mongoutil.FindOne[VersionTable](ctx, coll, bson.M{"key": key})
27+
if err == nil {
28+
ver, err := strconv.Atoi(res.Value)
29+
if err != nil {
30+
return false, fmt.Errorf("version %s parse error %w", res.Value, err)
31+
}
32+
if ver >= currentVersion {
33+
return true, nil
34+
}
35+
return false, nil
36+
} else if errors.Is(err, mongo.ErrNoDocuments) {
37+
return false, nil
38+
} else {
39+
return false, err
40+
}
41+
}
42+
43+
func SetVersion(coll *mongo.Collection, key string, version int) error {
44+
ctx, cancel := context.WithTimeout(context.Background(), time.Second*5)
45+
defer cancel()
46+
option := options.Update().SetUpsert(true)
47+
filter := bson.M{"key": key, "value": strconv.Itoa(version)}
48+
update := bson.M{"$set": bson.M{"key": key, "value": strconv.Itoa(version)}}
49+
return mongoutil.UpdateOne(ctx, coll, filter, update, false, option)
50+
}

0 commit comments

Comments
 (0)