Skip to content

Commit

Permalink
various fixes regarding getting and putting objects in the database
Browse files Browse the repository at this point in the history
  • Loading branch information
khaf committed May 4, 2015
1 parent 9d284a9 commit 0fcbfa8
Show file tree
Hide file tree
Showing 3 changed files with 41 additions and 27 deletions.
5 changes: 4 additions & 1 deletion client.go
Original file line number Diff line number Diff line change
Expand Up @@ -306,7 +306,10 @@ func (clnt *Client) Get(policy *BasePolicy, key *Key, binNames ...string) (*Reco
func (clnt *Client) GetObject(policy *BasePolicy, key *Key, obj interface{}) error {
policy = clnt.getUsablePolicy(policy)

binNames := objectMappings.getFields(reflect.ValueOf(obj).Type().Elem().Name())
rval := reflect.ValueOf(obj)
cacheObjectTags(rval)
binNames := objectMappings.getFields(rval)

command := newReadCommand(clnt.cluster, policy, key, binNames)
command.object = obj
if err := command.Execute(); err != nil {
Expand Down
59 changes: 33 additions & 26 deletions marshal.go
Original file line number Diff line number Diff line change
Expand Up @@ -120,18 +120,16 @@ func structToMap(s reflect.Value) map[string]interface{} {

binValue := valueToInterface(s.Field(i))

if binValue != nil {
if binMap == nil {
binMap = make(map[string]interface{}, numFields)
}

alias := fieldAlias(typeOfT.Field(i))
if alias == "" {
continue
}
if binMap == nil {
binMap = make(map[string]interface{}, numFields)
}

binMap[alias] = binValue
alias := fieldAlias(typeOfT.Field(i))
if alias == "" {
continue
}

binMap[alias] = binValue
}

return binMap
Expand All @@ -156,16 +154,14 @@ func marshal(v interface{}) []*Bin {

binValue := valueToInterface(s.Field(i))

if binValue != nil {
alias := fieldAlias(typeOfT.Field(i))
if alias == "" {
continue
}

bins[binCount].Name = alias
bins[binCount].Value = NewValue(binValue)
binCount++
alias := fieldAlias(typeOfT.Field(i))
if alias == "" {
continue
}

bins[binCount].Name = alias
bins[binCount].Value = NewValue(binValue)
binCount++
}

return bins[:binCount]
Expand All @@ -177,27 +173,32 @@ type SyncMap struct {
mutex sync.RWMutex
}

func (sm *SyncMap) setMapping(objType string, mapping map[string]string, fields []string) {
func (sm *SyncMap) setMapping(obj reflect.Value, mapping map[string]string, fields []string) {
objType := obj.Type().Name()
sm.mutex.Lock()
sm.objectMappings[objType] = mapping
sm.objectFields[objType] = fields
sm.mutex.Unlock()
}

func (sm *SyncMap) mappingExists(objType string) bool {
func (sm *SyncMap) mappingExists(obj reflect.Value) bool {
objType := obj.Type().Name()
sm.mutex.RLock()
_, exists := sm.objectMappings[objType]
sm.mutex.RUnlock()
return exists
}

func (sm *SyncMap) getMapping(objType string) map[string]string {
func (sm *SyncMap) getMapping(obj reflect.Value) map[string]string {
objType := obj.Type().Name()
sm.mutex.RLock()
mapping := sm.objectMappings[objType]
sm.mutex.RUnlock()
return mapping
}

func (sm *SyncMap) getFields(objType string) []string {
func (sm *SyncMap) getFields(obj reflect.Value) []string {
objType := obj.Type().Name()
sm.mutex.RLock()
fields := sm.objectFields[objType]
sm.mutex.RUnlock()
Expand All @@ -207,12 +208,18 @@ func (sm *SyncMap) getFields(objType string) []string {
var objectMappings = &SyncMap{objectMappings: map[string]map[string]string{}, objectFields: map[string][]string{}}

func cacheObjectTags(obj reflect.Value) {
objType := obj.Type().Name()
// exit if already processed
if objectMappings.mappingExists(objType) {
if objectMappings.mappingExists(obj) {
return
}

for obj.Kind() == reflect.Ptr {
if obj.IsNil() {
return
}
obj = reflect.Indirect(obj)
}

mapping := map[string]string{}
fields := []string{}

Expand All @@ -236,5 +243,5 @@ func cacheObjectTags(obj reflect.Value) {
}
}

objectMappings.setMapping(objType, mapping, fields)
objectMappings.setMapping(obj, mapping, fields)
}
4 changes: 4 additions & 0 deletions read_command.go
Original file line number Diff line number Diff line change
Expand Up @@ -226,6 +226,10 @@ func (cmd *readCommand) Execute() error {
}

func (cmd *readCommand) setObjectField(obj reflect.Value, fieldName string, value interface{}) error {
if value == nil {
return nil
}

// find the name based on tag mapping
iobj := reflect.Indirect(obj)
if name, exists := cmd.objectMappings[iobj.Type().Name()][fieldName]; exists {
Expand Down

0 comments on commit 0fcbfa8

Please sign in to comment.