/* logic: input: key, *struct a) Check if key has Id; yes/no no) INCR k:count set value as Id in struct b) Parse struct; returns [field, value, field, value, ...], [hashField, ...]. the hashField slice contains any optional properties which should be applied to before or after setting the struct in Redis (uniquity, index). c) Check unique fields and set unique fields d) Add the actual data from struct to a redis hash e) Add optional indexes f) if c, d, e did raise an error we need to cleanup the things we changed in the database. */ func Put(db *redis.Client, k *Key, s interface{}) (*Key, error) { mon := monitoring.BeginMeasuring("database:put") defer mon.EndMeasuring() prep := new(prepare) prep.key = k e := setId(db, s, prep) if e != nil { return nil, e } e = parseStruct(db, s, prep) if e != nil { return nil, e } for _, o := range prep.unique { uk := k.Unique(o.name, fmt.Sprintf("%v", *o.value)) var reply *redis.Reply // TODO: Watch key reply, e = db.Call("GET", uk) if e != nil { goto Error } if !reply.Nil() && reply.Elem.Int64() != k.Id() { e = newUniqueError(o.name, *o.value) goto Error } reply, e = db.Call("SET", uk, k.Id()) if e != nil { goto Error } prep.dirty = append(prep.dirty, uk) } _, e = db.Call(append([]interface{}{"HMSET", k.String()}, prep.args...)...) for _, o := range prep.index { ik := fmt.Sprintf("%v", *o.value) _, e = db.Call("SET", k.Index(o.name, ik), k.Id()) if e != nil { goto Error } prep.dirty = append(prep.dirty, ik) } return k, e Error: cleanup(db, prep) return nil, e }
func Get(db *redis.Client, k *Key, s interface{}) error { mon := monitoring.BeginMeasuring("database:get") reply, e := db.Call("HGETALL", k.String()) if e != nil { return e } if reply.Len() == 0 { return nilError } e = inflate(db, s, reply.Hash()) mon.EndMeasuring() return e }