/* File Name: Profile.go Copyright: 2021 Peernet s.r.o. Author: Peter Kleissner */ package blockchain // ProfileReadField reads the specified profile field. See ProfileX for the list of recognized fields. The encoding depends on the field type. Status is StatusX. func (blockchain *Blockchain) ProfileReadField(index uint16) (data []byte, status int) { found := false status = blockchain.Iterate(func(block *Block) (statusI int) { fields, err := decodeBlockRecordProfile(block.RecordsRaw) if err != nil { return StatusCorruptBlockRecord } else if len(fields) == 0 { return StatusOK } // Check if the field is available in the profile record. If there are multiple records, only return the latest one. for n := range fields { if fields[n].Type == index { data = fields[n].Data found = true } } return StatusOK }) if status != StatusOK { return nil, status } else if !found { return nil, StatusDataNotFound } return data, StatusOK } // ProfileList lists all profile fields. Status is StatusX. func (blockchain *Blockchain) ProfileList() (fields []BlockRecordProfile, status int) { uniqueFields := make(map[uint16][]byte) status = blockchain.Iterate(func(block *Block) (statusI int) { fields, err := decodeBlockRecordProfile(block.RecordsRaw) if err != nil { return StatusCorruptBlockRecord } for n := range fields { uniqueFields[fields[n].Type] = fields[n].Data } return StatusOK }) for key, value := range uniqueFields { fields = append(fields, BlockRecordProfile{Type: key, Data: value}) } return fields, status } // ProfileWrite writes profile fields and blobs to the blockchain. Status is StatusX. func (blockchain *Blockchain) ProfileWrite(fields []BlockRecordProfile) (newHeight, newVersion uint64, status int) { encoded, err := encodeBlockRecordProfile(fields) if err != nil { return 0, 0, StatusCorruptBlockRecord } return blockchain.Append(encoded) } // ProfileDelete deletes fields and blobs from the blockchain. Status is StatusX. func (blockchain *Blockchain) ProfileDelete(fields []uint16) (newHeight, newVersion uint64, status int) { return blockchain.IterateDeleteRecord(func(record *BlockRecordRaw) (deleteAction int) { if record.Type != RecordTypeProfile { return 0 // no action } existingFields, err := decodeBlockRecordProfile([]BlockRecordRaw{*record}) if err != nil || len(existingFields) != 1 { return 3 // error blockchain corrupt } for _, i := range fields { if i == existingFields[0].Type { // found a file ID to delete? return 1 // delete record } } return 0 // no action on record }) }