github.com/turingchain2020/turingchain@v1.1.21/common/db/table/table.go (about) 1 // Copyright Turing Corp. 2018 All Rights Reserved. 2 // Use of this source code is governed by a BSD-style 3 // license that can be found in the LICENSE file. 4 5 //Package table 实现一个基于kv的关系型数据库的表格功能 6 package table 7 8 import ( 9 "bytes" 10 "encoding/binary" 11 "errors" 12 "fmt" 13 "strings" 14 15 "github.com/turingchain2020/turingchain/common/db" 16 "github.com/turingchain2020/turingchain/types" 17 "github.com/turingchain2020/turingchain/util" 18 "github.com/golang/protobuf/proto" 19 ) 20 21 //设计结构: 22 /* 23 核心: 平衡 24 save: 25 数据保存: 26 tableprefix + tablename + Primary -> data 27 28 index: 29 tableprefix + tablemetaname + index + primary -> primary 30 31 read: 32 list by Primary -> 直接读出数据 33 list by index 34 35 根据index 先计算要读出的 primary list 36 从数据table读出数据(根据 primary key) 37 38 del: 39 利用 primaryKey + index 删除所有的 数据 和 索引 40 */ 41 42 //表关联设计 43 //指出是 添加 还是 删除 行 44 //primary key auto 的del 需要指定 primary key 45 const ( 46 None = iota 47 Add 48 Update 49 Del 50 ) 51 52 //meta key 53 const meta = sep + "m" + sep 54 const data = sep + "d" + sep 55 56 //RowMeta 定义行的操作 57 type RowMeta interface { 58 CreateRow() *Row 59 SetPayload(types.Message) error 60 Get(key string) ([]byte, error) 61 } 62 63 //Row 行操作 64 type Row struct { 65 Ty int 66 Primary []byte 67 Data types.Message 68 old types.Message 69 } 70 71 func encodeInt64(p int64) ([]byte, error) { 72 buf := new(bytes.Buffer) 73 err := binary.Write(buf, binary.LittleEndian, p) 74 if err != nil { 75 return nil, err 76 } 77 return buf.Bytes(), nil 78 } 79 80 func decodeInt64(p []byte) (int64, error) { 81 buf := bytes.NewBuffer(p) 82 var i int64 83 err := binary.Read(buf, binary.LittleEndian, &i) 84 if err != nil { 85 return 0, err 86 } 87 return i, nil 88 } 89 90 //Encode row 91 func (row *Row) Encode() ([]byte, error) { 92 b, err := encodeInt64(int64(len(row.Primary))) 93 if err != nil { 94 return nil, err 95 } 96 b = append(b, row.Primary...) 97 b = append(b, types.Encode(row.Data)...) 98 return b, nil 99 } 100 101 //DecodeRow from data 102 func DecodeRow(data []byte) ([]byte, []byte, error) { 103 if len(data) <= 8 { 104 return nil, nil, types.ErrDecode 105 } 106 l, err := decodeInt64(data[:8]) 107 if err != nil { 108 return nil, nil, err 109 } 110 if len(data) < int(l)+8 { 111 return nil, nil, types.ErrDecode 112 } 113 return data[8 : int(l)+8], data[int(l)+8:], nil 114 } 115 116 //Table 定一个表格, 并且添加 primary key, index key 117 type Table struct { 118 meta RowMeta 119 rows []*Row 120 rowmap map[string]*Row 121 kvdb db.KV 122 opt *Option 123 autoinc *Count 124 dataprefix string 125 metaprefix string 126 } 127 128 //Option table 的选项 129 type Option struct { 130 Prefix string 131 Name string 132 Primary string 133 Join bool 134 Index []string 135 } 136 137 const sep = "-" 138 const joinsep = "#" 139 140 //NewTable 新建一个表格 141 //primary 可以为: auto, 由系统自动创建 142 //index 可以为nil 143 func NewTable(rowmeta RowMeta, kvdb db.KV, opt *Option) (*Table, error) { 144 if len(opt.Index) > 16 { 145 return nil, ErrTooManyIndex 146 } 147 for _, index := range opt.Index { 148 if strings.Contains(index, sep) || index == "primary" { 149 return nil, ErrIndexKey 150 } 151 if !opt.Join && strings.Contains(index, joinsep) { 152 return nil, ErrIndexKey 153 } 154 } 155 if opt.Primary == "" { 156 opt.Primary = "auto" 157 } 158 if _, err := getPrimaryKey(rowmeta, opt.Primary); err != nil { 159 return nil, err 160 } 161 //不允许有 "-" 162 if strings.Contains(opt.Name, sep) { 163 return nil, ErrTablePrefixOrTableName 164 } 165 //非jointable 不允许 "#" 166 if !opt.Join && strings.Contains(opt.Name, joinsep) { 167 return nil, ErrTablePrefixOrTableName 168 } 169 dataprefix := opt.Prefix + sep + opt.Name + data 170 metaprefix := opt.Prefix + sep + opt.Name + meta 171 count := NewCount(opt.Prefix, opt.Name+sep+"autoinc"+sep, kvdb) 172 return &Table{ 173 meta: rowmeta, 174 kvdb: kvdb, 175 rowmap: make(map[string]*Row), 176 opt: opt, 177 autoinc: count, 178 dataprefix: dataprefix, 179 metaprefix: metaprefix}, nil 180 } 181 182 func getPrimaryKey(meta RowMeta, primary string) ([]byte, error) { 183 if primary == "" { 184 return nil, ErrEmptyPrimaryKey 185 } 186 if strings.Contains(primary, sep) { 187 return nil, ErrPrimaryKey 188 } 189 if primary != "auto" { 190 key, err := meta.Get(primary) 191 return key, err 192 } 193 return nil, nil 194 } 195 196 func (table *Table) addRowCache(row *Row) { 197 primary := string(row.Primary) 198 if row.Ty == Del { 199 delete(table.rowmap, primary) 200 } else if row.Ty == Add || row.Ty == Update { 201 table.rowmap[primary] = row 202 } 203 table.rows = append(table.rows, row) 204 } 205 206 func (table *Table) delRowCache(row *Row) { 207 row.Ty = None 208 primary := string(row.Primary) 209 delete(table.rowmap, primary) 210 } 211 212 func (table *Table) mergeCache(rows []*Row, indexName string, indexValue []byte) ([]*Row, error) { 213 replaced := make(map[string]bool) 214 for i, row := range rows { 215 if cacherow, ok := table.rowmap[string(row.Primary)]; ok { 216 rows[i] = cacherow 217 replaced[string(row.Primary)] = true 218 } 219 } 220 //add not in db but in cache rows 221 for _, row := range table.rowmap { 222 if _, ok := replaced[string(row.Primary)]; ok { 223 continue 224 } 225 v, err := table.index(row, indexName) 226 if err != nil { 227 return nil, err 228 } 229 if bytes.Equal(v, indexValue) { 230 rows = append(rows, row) 231 } 232 } 233 return rows, nil 234 } 235 236 func (table *Table) findRow(primary []byte) (*Row, bool, error) { 237 if row, ok := table.rowmap[string(primary)]; ok { 238 return row, true, nil 239 } 240 row, err := table.GetData(primary) 241 return row, false, err 242 } 243 244 func (table *Table) hasIndex(name string) bool { 245 for _, index := range table.opt.Index { 246 if index == name { 247 return true 248 } 249 } 250 return false 251 } 252 253 func (table *Table) canGet(name string) bool { 254 row := table.meta.CreateRow() 255 err := table.meta.SetPayload(row.Data) 256 if err != nil { 257 return false 258 } 259 _, err = table.meta.Get(name) 260 return err == nil 261 } 262 263 func (table *Table) checkIndex(data types.Message) error { 264 err := table.meta.SetPayload(data) 265 if err != nil { 266 return err 267 } 268 if _, err := getPrimaryKey(table.meta, table.opt.Primary); err != nil { 269 return err 270 } 271 for i := 0; i < len(table.opt.Index); i++ { 272 _, err := table.meta.Get(table.opt.Index[i]) 273 if err != nil { 274 return err 275 } 276 } 277 return nil 278 } 279 280 func (table *Table) getPrimaryAuto() ([]byte, error) { 281 i, err := table.autoinc.Inc() 282 if err != nil { 283 return nil, err 284 } 285 return []byte(pad(i)), nil 286 } 287 288 //primaryKey 获取主键 289 //1. auto 的情况下,只能自增。 290 //2. 没有auto的情况下从数据中取 291 func (table *Table) primaryKey(data types.Message) (primaryKey []byte, err error) { 292 if table.opt.Primary == "auto" { 293 primaryKey, err = table.getPrimaryAuto() 294 if err != nil { 295 return nil, err 296 } 297 } else { 298 primaryKey, err = table.getPrimaryFromData(data) 299 } 300 return 301 } 302 303 func (table *Table) getPrimaryFromData(data types.Message) (primaryKey []byte, err error) { 304 err = table.meta.SetPayload(data) 305 if err != nil { 306 return nil, err 307 } 308 primaryKey, err = getPrimaryKey(table.meta, table.opt.Primary) 309 if err != nil { 310 return nil, err 311 } 312 return 313 } 314 315 //ListIndex list table index 316 func (table *Table) ListIndex(indexName string, prefix []byte, primaryKey []byte, count, direction int32) (rows []*Row, err error) { 317 kvdb, ok := table.kvdb.(db.KVDB) 318 if !ok { 319 return nil, errors.New("list only support KVDB interface") 320 } 321 query := &Query{table: table, kvdb: kvdb} 322 return query.ListIndex(indexName, prefix, primaryKey, count, direction) 323 } 324 325 //Replace 如果有重复的,那么替换 326 func (table *Table) Replace(data types.Message) error { 327 if err := table.checkIndex(data); err != nil { 328 return err 329 } 330 primaryKey, err := table.primaryKey(data) 331 if err != nil { 332 return err 333 } 334 //如果是auto的情况,一定是添加 335 if table.opt.Primary == "auto" { 336 table.addRowCache(&Row{Data: data, Primary: primaryKey, Ty: Add}) 337 return nil 338 } 339 //如果没有找到行, 那么添加 340 //TODO: 优化保存策略,不需要修改没有变化的index 341 row, incache, err := table.findRow(primaryKey) 342 if err == types.ErrNotFound { 343 table.addRowCache(&Row{Data: data, Primary: primaryKey, Ty: Add}) 344 return nil 345 } 346 //update or add 347 if incache { 348 row.Data = data 349 return nil 350 } 351 //更新数据 352 table.addRowCache(&Row{Data: data, Primary: primaryKey, Ty: Update, old: row.Data}) 353 return nil 354 } 355 356 //Add 在表格中添加一行 357 func (table *Table) Add(data types.Message) error { 358 if err := table.checkIndex(data); err != nil { 359 return err 360 } 361 primaryKey, err := table.primaryKey(data) 362 if err != nil { 363 return err 364 } 365 //find in cache + db 366 _, _, err = table.findRow(primaryKey) 367 if err != types.ErrNotFound { 368 return ErrDupPrimaryKey 369 } 370 //检查cache中是否有重复,有重复也返回错误 371 table.addRowCache(&Row{Data: data, Primary: primaryKey, Ty: Add}) 372 return nil 373 } 374 375 //Update 更新数据库 376 func (table *Table) Update(primaryKey []byte, newdata types.Message) (err error) { 377 if err := table.checkIndex(newdata); err != nil { 378 return err 379 } 380 p1, err := table.getPrimaryFromData(newdata) 381 if err != nil { 382 return err 383 } 384 if !bytes.Equal(p1, primaryKey) { 385 return types.ErrInvalidParam 386 } 387 row, incache, err := table.findRow(primaryKey) 388 //查询发生错误 389 if err != nil { 390 return err 391 } 392 //update and add 393 if incache { 394 row.Data = newdata 395 return nil 396 } 397 table.addRowCache(&Row{Data: newdata, Primary: primaryKey, Ty: Update, old: row.Data}) 398 return nil 399 } 400 401 //Del 在表格中删除一行(包括删除索引) 402 func (table *Table) Del(primaryKey []byte) error { 403 row, incache, err := table.findRow(primaryKey) 404 if err != nil { 405 return err 406 } 407 if incache { 408 rowty := row.Ty 409 table.delRowCache(row) 410 if rowty == Add { 411 return nil 412 } 413 } 414 //copy row 415 delrow := *row 416 delrow.Ty = Del 417 table.addRowCache(&delrow) 418 return nil 419 } 420 421 //DelRow 删除一行 422 func (table *Table) DelRow(data types.Message) error { 423 primaryKey, err := table.primaryKey(data) 424 if err != nil { 425 return err 426 } 427 return table.Del(primaryKey) 428 } 429 430 //getDataKey data key 构造 431 func (table *Table) getDataKey(primaryKey []byte) []byte { 432 return append([]byte(table.dataprefix), primaryKey...) 433 } 434 435 //GetIndexKey data key 构造 436 func (table *Table) getIndexKey(indexName string, index, primaryKey []byte) []byte { 437 key := table.indexPrefix(indexName) 438 key = append(key, index...) 439 key = append(key, []byte(sep)...) 440 key = append(key, primaryKey...) 441 return key 442 } 443 444 func (table *Table) primaryPrefix() []byte { 445 return []byte(table.dataprefix) 446 } 447 448 func (table *Table) indexPrefix(indexName string) []byte { 449 key := append([]byte(table.metaprefix), []byte(indexName+sep)...) 450 return key 451 } 452 453 func (table *Table) index(row *Row, indexName string) ([]byte, error) { 454 err := table.meta.SetPayload(row.Data) 455 if err != nil { 456 return nil, err 457 } 458 return table.meta.Get(indexName) 459 } 460 461 func (table *Table) getData(primaryKey []byte) ([]byte, error) { 462 key := table.getDataKey(primaryKey) 463 value, err := table.kvdb.Get(key) 464 if err != nil { 465 return nil, err 466 } 467 return value, nil 468 } 469 470 //GetData 根据主键获取数据 471 func (table *Table) GetData(primaryKey []byte) (*Row, error) { 472 value, err := table.getData(primaryKey) 473 if err != nil { 474 return nil, err 475 } 476 return table.getRow(value) 477 } 478 479 func (table *Table) getRow(value []byte) (*Row, error) { 480 primary, data, err := DecodeRow(value) 481 if err != nil { 482 return nil, err 483 } 484 row := table.meta.CreateRow() 485 row.Primary = primary 486 err = types.Decode(data, row.Data) 487 if err != nil { 488 return nil, err 489 } 490 return row, nil 491 } 492 493 //Save 保存表格 494 func (table *Table) Save() (kvs []*types.KeyValue, err error) { 495 for _, row := range table.rows { 496 kvlist, err := table.saveRow(row) 497 if err != nil { 498 return nil, err 499 } 500 kvs = append(kvs, kvlist...) 501 } 502 kvlist, err := table.autoinc.Save() 503 if err != nil { 504 return nil, err 505 } 506 kvs = append(kvs, kvlist...) 507 //del cache 508 table.rowmap = make(map[string]*Row) 509 table.rows = nil 510 return util.DelDupKey(kvs), nil 511 } 512 513 func pad(i int64) string { 514 return fmt.Sprintf("%020d", i) 515 } 516 517 func (table *Table) saveRow(row *Row) (kvs []*types.KeyValue, err error) { 518 if row.Ty == Del { 519 return table.delRow(row) 520 } else if row.Ty == Add { 521 return table.addRow(row) 522 } else if row.Ty == Update { 523 return table.updateRow(row) 524 } else if row.Ty == None { 525 return nil, nil 526 } 527 return nil, errors.New("save table unknow action") 528 } 529 530 func (table *Table) delRow(row *Row) (kvs []*types.KeyValue, err error) { 531 if !table.opt.Join { 532 deldata := &types.KeyValue{Key: table.getDataKey(row.Primary)} 533 kvs = append(kvs, deldata) 534 } 535 for _, index := range table.opt.Index { 536 indexkey, err := table.index(row, index) 537 if err != nil { 538 return nil, err 539 } 540 delindex := &types.KeyValue{Key: table.getIndexKey(index, indexkey, row.Primary)} 541 kvs = append(kvs, delindex) 542 } 543 return kvs, nil 544 } 545 546 func (table *Table) addRow(row *Row) (kvs []*types.KeyValue, err error) { 547 if !table.opt.Join { 548 data, err := row.Encode() 549 if err != nil { 550 return nil, err 551 } 552 adddata := &types.KeyValue{Key: table.getDataKey(row.Primary), Value: data} 553 kvs = append(kvs, adddata) 554 } 555 for _, index := range table.opt.Index { 556 indexkey, err := table.index(row, index) 557 if err != nil { 558 return nil, err 559 } 560 addindex := &types.KeyValue{Key: table.getIndexKey(index, indexkey, row.Primary), Value: row.Primary} 561 kvs = append(kvs, addindex) 562 } 563 return kvs, nil 564 } 565 566 func (table *Table) updateRow(row *Row) (kvs []*types.KeyValue, err error) { 567 if proto.Equal(row.Data, row.old) { 568 return nil, nil 569 } 570 if !table.opt.Join { 571 data, err := row.Encode() 572 if err != nil { 573 return nil, err 574 } 575 adddata := &types.KeyValue{Key: table.getDataKey(row.Primary), Value: data} 576 kvs = append(kvs, adddata) 577 } 578 oldrow := &Row{Data: row.old} 579 for _, index := range table.opt.Index { 580 indexkey, oldkey, ismodify, err := table.getModify(row, oldrow, index) 581 if err != nil { 582 return nil, err 583 } 584 if !ismodify { 585 continue 586 } 587 //del old 588 delindex := &types.KeyValue{Key: table.getIndexKey(index, oldkey, row.Primary)} 589 kvs = append(kvs, delindex) 590 //add new 591 addindex := &types.KeyValue{Key: table.getIndexKey(index, indexkey, row.Primary), Value: row.Primary} 592 kvs = append(kvs, addindex) 593 } 594 return kvs, nil 595 } 596 597 func (table *Table) getModify(row, oldrow *Row, index string) ([]byte, []byte, bool, error) { 598 if oldrow.Data == nil { 599 return nil, nil, false, ErrNilValue 600 } 601 indexkey, err := table.index(row, index) 602 if err != nil { 603 return nil, nil, false, err 604 } 605 oldkey, err := table.index(oldrow, index) 606 if err != nil { 607 return nil, nil, false, err 608 } 609 if bytes.Equal(indexkey, oldkey) { 610 return indexkey, oldkey, false, nil 611 } 612 return indexkey, oldkey, true, nil 613 } 614 615 //GetQuery 获取查询结构(允许传入 kvdb 为nil) 616 func (table *Table) GetQuery(kvdb db.KVDB) *Query { 617 if kvdb == nil { 618 var ok bool 619 kvdb, ok = table.kvdb.(db.KVDB) 620 if !ok { 621 return nil 622 } 623 } 624 return &Query{table: table, kvdb: kvdb} 625 } 626 627 func (table *Table) getMeta() RowMeta { 628 return table.meta 629 } 630 631 //GetMeta 获取meta 632 func (table *Table) GetMeta() RowMeta { 633 return table.getMeta() 634 } 635 636 func (table *Table) getOpt() *Option { 637 return table.opt 638 }