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  }