github.com/linapex/ethereum-go-chinese@v0.0.0-20190316121929-f8b7a73c3fa1/swarm/shed/schema.go (about)

     1  
     2  //<developer>
     3  //    <name>linapex 曹一峰</name>
     4  //    <email>linapex@163.com</email>
     5  //    <wx>superexc</wx>
     6  //    <qqgroup>128148617</qqgroup>
     7  //    <url>https://jsq.ink</url>
     8  //    <role>pku engineer</role>
     9  //    <date>2019-03-16 19:16:44</date>
    10  //</624450118044618752>
    11  
    12  
    13  package shed
    14  
    15  import (
    16  	"encoding/json"
    17  	"errors"
    18  	"fmt"
    19  )
    20  
    21  var (
    22  //用于存储架构的LevelDB键值。
    23  	keySchema = []byte{0}
    24  //所有字段类型的leveldb键前缀。
    25  //将通过将名称值附加到此前缀来构造LevelDB键。
    26  	keyPrefixFields byte = 1
    27  //索引键起始的级别数据库键前缀。
    28  //每个索引都有自己的键前缀,这个值定义了第一个。
    29  keyPrefixIndexStart byte = 2 //问:或者可能是更高的数字,比如7,为潜在的特定性能提供更多的空间。
    30  )
    31  
    32  //架构用于序列化已知的数据库结构信息。
    33  type schema struct {
    34  Fields  map[string]fieldSpec `json:"fields"`  //键是字段名
    35  Indexes map[byte]indexSpec   `json:"indexes"` //键是索引前缀字节
    36  }
    37  
    38  //fieldspec保存有关特定字段的信息。
    39  //它不需要名称字段,因为它包含在
    40  //架构。字段映射键。
    41  type fieldSpec struct {
    42  	Type string `json:"type"`
    43  }
    44  
    45  //indxspec保存有关特定索引的信息。
    46  //它不包含索引类型,因为索引没有类型。
    47  type indexSpec struct {
    48  	Name string `json:"name"`
    49  }
    50  
    51  //SchemaFieldKey检索的完整级别数据库键
    52  //一个特定的字段构成了模式定义。
    53  func (db *DB) schemaFieldKey(name, fieldType string) (key []byte, err error) {
    54  	if name == "" {
    55  		return nil, errors.New("field name can not be blank")
    56  	}
    57  	if fieldType == "" {
    58  		return nil, errors.New("field type can not be blank")
    59  	}
    60  	s, err := db.getSchema()
    61  	if err != nil {
    62  		return nil, err
    63  	}
    64  	var found bool
    65  	for n, f := range s.Fields {
    66  		if n == name {
    67  			if f.Type != fieldType {
    68  				return nil, fmt.Errorf("field %q of type %q stored as %q in db", name, fieldType, f.Type)
    69  			}
    70  			break
    71  		}
    72  	}
    73  	if !found {
    74  		s.Fields[name] = fieldSpec{
    75  			Type: fieldType,
    76  		}
    77  		err := db.putSchema(s)
    78  		if err != nil {
    79  			return nil, err
    80  		}
    81  	}
    82  	return append([]byte{keyPrefixFields}, []byte(name)...), nil
    83  }
    84  
    85  //SchemaIndexID检索的完整级别数据库前缀
    86  //一种特殊的索引。
    87  func (db *DB) schemaIndexPrefix(name string) (id byte, err error) {
    88  	if name == "" {
    89  		return 0, errors.New("index name can not be blank")
    90  	}
    91  	s, err := db.getSchema()
    92  	if err != nil {
    93  		return 0, err
    94  	}
    95  	nextID := keyPrefixIndexStart
    96  	for i, f := range s.Indexes {
    97  		if i >= nextID {
    98  			nextID = i + 1
    99  		}
   100  		if f.Name == name {
   101  			return i, nil
   102  		}
   103  	}
   104  	id = nextID
   105  	s.Indexes[id] = indexSpec{
   106  		Name: name,
   107  	}
   108  	return id, db.putSchema(s)
   109  }
   110  
   111  //GetSchema从中检索完整的架构
   112  //数据库。
   113  func (db *DB) getSchema() (s schema, err error) {
   114  	b, err := db.Get(keySchema)
   115  	if err != nil {
   116  		return s, err
   117  	}
   118  	err = json.Unmarshal(b, &s)
   119  	return s, err
   120  }
   121  
   122  //PutSchema将完整的架构存储到
   123  //数据库。
   124  func (db *DB) putSchema(s schema) (err error) {
   125  	b, err := json.Marshal(s)
   126  	if err != nil {
   127  		return err
   128  	}
   129  	return db.Put(keySchema, b)
   130  }
   131