github.com/janelia-flyem/dvid@v1.0.0/datatype/neuronjson/schema.go (about) 1 package neuronjson 2 3 import ( 4 "fmt" 5 6 "github.com/janelia-flyem/dvid/datastore" 7 "github.com/janelia-flyem/dvid/dvid" 8 "github.com/janelia-flyem/dvid/storage" 9 "github.com/santhosh-tekuri/jsonschema/v5" 10 ) 11 12 // Metadata key-value support (all non-neuron annotations) 13 14 // load metadata from storage 15 func (d *Data) loadMetadata(ctx storage.VersionedCtx, meta Schema) (val []byte, err error) { 16 var tkey storage.TKey 17 if tkey, err = getMetadataKey(meta); err != nil { 18 return 19 } 20 var db storage.KeyValueDB 21 if db, err = datastore.GetKeyValueDB(d); err != nil { 22 return 23 } 24 var byteVal []byte 25 if byteVal, err = db.Get(ctx, tkey); err != nil { 26 return 27 } 28 return byteVal, nil 29 } 30 31 // gets metadata from either in-memory db if HEAD or from store 32 func (d *Data) getMetadata(ctx storage.VersionedCtx, meta Schema) (val []byte, err error) { 33 if ctx.Head() { 34 d.metadataMu.RLock() 35 defer d.metadataMu.RUnlock() 36 if val, found := d.metadata[meta]; found { 37 return val, nil 38 } else { 39 return nil, nil 40 } 41 } 42 return d.loadMetadata(ctx, meta) 43 } 44 45 // get fully compiled JSON schema for use -- TODO 46 func (d *Data) getJSONSchema(ctx storage.VersionedCtx) (sch *jsonschema.Schema, err error) { 47 if ctx.Head() { 48 d.metadataMu.RLock() 49 sch = d.compiledSchema 50 d.metadataMu.RUnlock() 51 if sch != nil { 52 return 53 } 54 } 55 56 var tkey storage.TKey 57 if tkey, err = getMetadataKey(JSONSchema); err != nil { 58 return 59 } 60 var db storage.KeyValueDB 61 if db, err = datastore.GetKeyValueDB(d); err != nil { 62 return 63 } 64 var byteVal []byte 65 if byteVal, err = db.Get(ctx, tkey); err != nil { 66 return 67 } 68 if len(byteVal) == 0 { 69 return nil, fmt.Errorf("no JSON Schema available") 70 } 71 if ctx.Head() { 72 d.metadataMu.RLock() 73 d.metadata[JSONSchema] = byteVal 74 d.metadataMu.RUnlock() 75 } 76 77 sch, err = jsonschema.CompileString("schema.json", string(byteVal)) 78 if err != nil { 79 return 80 } 81 if sch == nil { 82 return nil, fmt.Errorf("no JSON Schema available") 83 } 84 return 85 } 86 87 func (d *Data) putMetadata(ctx storage.VersionedCtx, val []byte, meta Schema) (err error) { 88 var tkey storage.TKey 89 if tkey, err = getMetadataKey(meta); err != nil { 90 return 91 } 92 var db storage.KeyValueDB 93 if db, err = datastore.GetKeyValueDB(d); err != nil { 94 return 95 } 96 if err = db.Put(ctx, tkey, val); err != nil { 97 return 98 } 99 100 // If we could persist metadata, add it to in-memory db if head. 101 if ctx.Head() { 102 d.metadataMu.Lock() 103 d.metadata[meta] = val 104 if meta == JSONSchema { 105 d.compiledSchema, err = jsonschema.CompileString("schema.json", string(val)) 106 if err != nil { 107 d.compiledSchema = nil 108 dvid.Errorf("Unable to compile json schema: %v\n", err) 109 } 110 } 111 d.metadataMu.Unlock() 112 } 113 return nil 114 } 115 116 func (d *Data) metadataExists(ctx storage.VersionedCtx, meta Schema) (exists bool, err error) { 117 if ctx.Head() { 118 d.metadataMu.RLock() 119 defer d.metadataMu.RUnlock() 120 _, found := d.metadata[meta] 121 return found, nil 122 } 123 var tkey storage.TKey 124 if tkey, err = getMetadataKey(meta); err != nil { 125 return 126 } 127 var db storage.KeyValueDB 128 if db, err = datastore.GetKeyValueDB(d); err != nil { 129 return 130 } 131 return db.Exists(ctx, tkey) 132 } 133 134 func (d *Data) deleteMetadata(ctx storage.VersionedCtx, meta Schema) (err error) { 135 var tkey storage.TKey 136 if tkey, err = getMetadataKey(meta); err != nil { 137 return 138 } 139 var db storage.KeyValueDB 140 if db, err = datastore.GetKeyValueDB(d); err != nil { 141 return 142 } 143 if err = db.Delete(ctx, tkey); err != nil { 144 return 145 } 146 if ctx.Head() { 147 d.metadataMu.Lock() 148 defer d.metadataMu.Unlock() 149 delete(d.metadata, meta) 150 } 151 return nil 152 }