-
Notifications
You must be signed in to change notification settings - Fork 0
/
Copy pathfile_store.go
148 lines (132 loc) · 4.13 KB
/
file_store.go
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
137
138
139
140
141
142
143
144
145
146
147
148
package database
import (
"cloud.google.com/go/firestore"
"context"
"fmt"
"github.com/ninjahome/web-bridge/util"
"google.golang.org/api/option"
"os"
"sync"
"time"
)
const (
DefaultFirestoreProjectID = "dessage"
DefaultDatabaseID = "dessage-release"
DefaultDBTimeOut = 10 * time.Second
DBTableNJUser = "ninja-user"
DBTableTWUser = "twitter-user"
DBTableTWUserAccToken = "twitter-user-access-token"
DBTableTWUserAccTokenV2 = "twitter-user-access-token_v2"
DBTableWeb3Bindings = "web3-bindings"
DBTableTweetsPosted = "tweets-posted"
DBTableTweetsStatus = "tweets-payment-status"
DBTableTweetsVoted = "tweets-voted"
DBTableTweetsSubStatus = "vote-status"
DBTableTweetsImages = "raw_img"
DBTableTweetsThumbImages = "thumb_img"
DBTableUserPoints = "user_points"
)
/*******************************************************************************************************
*
* Database Logic
*
******************************************************************************************************/
var _dbInst *DbManager
var databaseOnce sync.Once
type DbManager struct {
fileCli *firestore.Client
ctx context.Context
cancel context.CancelFunc
}
func DbInst() *DbManager {
databaseOnce.Do(func() {
_dbInst = newDb()
})
return _dbInst
}
func newDb() *DbManager {
ctx, cancel := context.WithCancel(context.Background())
var client *firestore.Client
var err error
if __dbConf.LocalRun {
_ = os.Setenv("FIRESTORE_EMULATOR_HOST", "localhost:8080")
client, err = firestore.NewClientWithDatabase(ctx, __dbConf.ProjectID, __dbConf.DatabaseID)
} else {
client, err = firestore.NewClientWithDatabase(ctx, __dbConf.ProjectID,
__dbConf.DatabaseID, option.WithCredentialsFile(__dbConf.KeyFilePath))
}
if err != nil {
panic(err)
}
var dbm = &DbManager{
fileCli: client,
ctx: ctx,
cancel: cancel,
}
return dbm
}
func (dm *DbManager) BindingWeb3ID(bindData *Web3Binding, twMeta *TWUserInfo) (*NinjaUsrInfo, error) {
var ethAddr = bindData.EthAddr
opCtx, cancel := context.WithTimeout(dm.ctx, DefaultDBTimeOut)
defer cancel()
err := dm.fileCli.RunTransaction(opCtx, func(ctx context.Context, tx *firestore.Transaction) error {
// 检查 NJ 用户基本数据
njUserDoc := dm.fileCli.Collection(DBTableNJUser).Doc(ethAddr)
doc, err := tx.Get(njUserDoc)
if err != nil {
util.LogInst().Err(err).Str("eth-addr", ethAddr).Msg("no nj user sign in data")
return err
}
nu := &NinjaUsrInfo{}
err = doc.DataTo(nu)
if err != nil {
util.LogInst().Err(err).Str("eth-addr", ethAddr).Msg("parse nj user failed")
return err
}
if len(nu.TwID) > 0 {
util.LogInst().Err(err).Str("eth-addr", ethAddr).
Str("twitter-id", nu.TwID).Msg("duplicate web3 binding")
return fmt.Errorf("duplicate web3 binding")
}
// 设置 Twitter 元数据绑定
twitterDoc := dm.fileCli.Collection(DBTableTWUser).Doc(twMeta.ID)
err = tx.Set(twitterDoc, twMeta)
if err != nil {
util.LogInst().Err(err).Str("twitter-id", twMeta.ID).Msg("update twitter meta failed")
return err
}
// 设置 Web3 绑定
bindDoc := dm.fileCli.Collection(DBTableWeb3Bindings).Doc(ethAddr)
err = tx.Set(bindDoc, bindData)
if err != nil {
util.LogInst().Err(err).Str("eth-addr", ethAddr).
Str("twitter-id", twMeta.ID).Msg("update web3 binding failed")
return err
}
// 更新 NJ 用户基本数据
nu.TwID = bindData.TwitterID
err = tx.Set(njUserDoc, nu, firestore.Merge([]string{"tw_id"}))
if err != nil {
util.LogInst().Err(err).Str("eth-addr", ethAddr).
Str("twitter-id", nu.TwID).Msg("update nj user failed")
return err
}
return nil
})
if err != nil {
return nil, err
}
njUserDoc := dm.fileCli.Collection(DBTableNJUser).Doc(ethAddr)
docSnapshot, err := njUserDoc.Get(opCtx)
if err != nil {
util.LogInst().Err(err).Str("eth-addr", ethAddr).Msg("Failed to get updated nj user data")
return nil, err
}
updatedNu := &NinjaUsrInfo{}
err = docSnapshot.DataTo(updatedNu)
if err != nil {
util.LogInst().Err(err).Str("eth-addr", ethAddr).Msg("Failed to decode updated nj user data")
return nil, err
}
return updatedNu, nil
}