github.com/turingchain2020/turingchain@v1.1.21/executor/localdb.go (about) 1 package executor 2 3 import ( 4 "github.com/turingchain2020/turingchain/client" 5 "github.com/turingchain2020/turingchain/common/db" 6 "github.com/turingchain2020/turingchain/queue" 7 "github.com/turingchain2020/turingchain/types" 8 ) 9 10 //LocalDB 本地数据库,类似localdb,不加入区块链的状态。 11 //数据库只读,不能落盘 12 //数据的get set 主要经过 cache 13 //如果需要进行list, 那么把get set 的内容加入到 后端数据库 14 type LocalDB struct { 15 cache map[string][]byte 16 txcache map[string][]byte 17 keys []string 18 intx bool 19 hasbegin bool 20 kvs []*types.KeyValue 21 txid *types.Int64 22 client queue.Client 23 api client.QueueProtocolAPI 24 disableread bool 25 disablewrite bool 26 } 27 28 //NewLocalDB 创建一个新的LocalDB 29 func NewLocalDB(cli queue.Client, readOnly bool) db.KVDB { 30 api, err := client.New(cli, nil) 31 if err != nil { 32 panic(err) 33 } 34 txid, err := api.LocalNew(readOnly) 35 if err != nil { 36 panic(err) 37 } 38 return &LocalDB{ 39 cache: make(map[string][]byte), 40 txid: txid, 41 client: cli, 42 api: api, 43 } 44 } 45 46 //DisableRead 禁止读取LocalDB数据库 47 func (l *LocalDB) DisableRead() { 48 l.disableread = true 49 } 50 51 //DisableWrite 禁止写LocalDB数据库 52 func (l *LocalDB) DisableWrite() { 53 l.disablewrite = true 54 } 55 56 //EnableRead 启动读取LocalDB数据库 57 func (l *LocalDB) EnableRead() { 58 l.disableread = false 59 } 60 61 //EnableWrite 启动写LocalDB数据库 62 func (l *LocalDB) EnableWrite() { 63 l.disablewrite = false 64 } 65 66 func (l *LocalDB) resetTx() { 67 l.intx = false 68 l.txcache = nil 69 l.keys = nil 70 l.hasbegin = false 71 } 72 73 // StartTx reset state db keys 74 func (l *LocalDB) StartTx() { 75 l.keys = nil 76 } 77 78 // GetSetKeys get state db set keys 79 func (l *LocalDB) GetSetKeys() (keys []string) { 80 return l.keys 81 } 82 83 //Begin 开始一个事务 84 func (l *LocalDB) Begin() { 85 l.intx = true 86 l.keys = nil 87 l.txcache = nil 88 l.hasbegin = false 89 } 90 91 func (l *LocalDB) begin() { 92 err := l.api.LocalBegin(l.txid) 93 if err != nil { 94 panic(err) 95 } 96 } 97 98 //第一次save 的时候,远程做一个 begin 操作,开始事务 99 func (l *LocalDB) save() error { 100 if l.kvs != nil { 101 if !l.hasbegin { 102 l.begin() 103 l.hasbegin = true 104 } 105 param := &types.LocalDBSet{Txid: l.txid.Data} 106 param.KV = l.kvs 107 err := l.api.LocalSet(param) 108 if err != nil { 109 return err 110 } 111 l.kvs = nil 112 } 113 return nil 114 } 115 116 //Commit 提交一个事务 117 func (l *LocalDB) Commit() error { 118 for k, v := range l.txcache { 119 l.cache[k] = v 120 } 121 err := l.save() 122 if err != nil { 123 return err 124 } 125 if l.hasbegin { 126 err = l.api.LocalCommit(l.txid) 127 } 128 l.resetTx() 129 return err 130 } 131 132 //Close 提交一个事务 133 func (l *LocalDB) Close() error { 134 l.cache = nil 135 l.resetTx() 136 err := l.api.LocalClose(l.txid) 137 return err 138 } 139 140 //Rollback 回滚修改 141 func (l *LocalDB) Rollback() { 142 if l.hasbegin { 143 err := l.api.LocalRollback(l.txid) 144 if err != nil { 145 panic(err) 146 } 147 } 148 l.resetTx() 149 } 150 151 //Get 获取key 152 func (l *LocalDB) Get(key []byte) ([]byte, error) { 153 if l.disableread { 154 return nil, types.ErrDisableRead 155 } 156 skey := string(key) 157 if l.intx && l.txcache != nil { 158 if value, ok := l.txcache[skey]; ok { 159 return value, nil 160 } 161 } 162 if value, ok := l.cache[skey]; ok { 163 if value == nil { 164 return nil, types.ErrNotFound 165 } 166 return value, nil 167 } 168 query := &types.LocalDBGet{Txid: l.txid.Data, Keys: [][]byte{key}} 169 resp, err := l.api.LocalGet(query) 170 if err != nil { 171 panic(err) //no happen for ever 172 } 173 if nil == resp.Values { 174 l.cache[skey] = nil 175 return nil, types.ErrNotFound 176 } 177 value := resp.Values[0] 178 if value == nil { 179 l.cache[skey] = nil 180 return nil, types.ErrNotFound 181 } 182 l.cache[skey] = value 183 return value, nil 184 } 185 186 //Set 获取key 187 func (l *LocalDB) Set(key []byte, value []byte) error { 188 if l.disablewrite { 189 return types.ErrDisableWrite 190 } 191 skey := string(key) 192 if l.intx { 193 if l.txcache == nil { 194 l.txcache = make(map[string][]byte) 195 } 196 l.keys = append(l.keys, skey) 197 setmap(l.txcache, skey, value) 198 } else { 199 setmap(l.cache, skey, value) 200 } 201 l.kvs = append(l.kvs, &types.KeyValue{Key: key, Value: value}) 202 return nil 203 } 204 205 // List 从数据库中查询数据列表 206 func (l *LocalDB) List(prefix, key []byte, count, direction int32) ([][]byte, error) { 207 if l.disableread { 208 return nil, types.ErrDisableRead 209 } 210 err := l.save() 211 if err != nil { 212 return nil, err 213 } 214 query := &types.LocalDBList{Txid: l.txid.Data, Prefix: prefix, Key: key, Count: count, Direction: direction} 215 resp, err := l.api.LocalList(query) 216 if err != nil { 217 panic(err) //no happen for ever 218 } 219 values := resp.Values 220 if values == nil { 221 //panic(string(key)) 222 return nil, types.ErrNotFound 223 } 224 return values, nil 225 } 226 227 // PrefixCount 从数据库中查询指定前缀的key的数量 228 func (l *LocalDB) PrefixCount(prefix []byte) (count int64) { 229 panic("localdb not support PrefixCount") 230 }