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