Example #1
0
// ReadMultiple gets the values from redis in a single call by pipelining
func (s *Store) ReadMultiple(i interface{}) error {
	v := reflect.ValueOf(i)

	if v.Kind() == reflect.Ptr {
		v = v.Elem()
	}

	if v.Kind() != reflect.Slice {
		return errors.New("store: value must be a a slice")
	}

	c := s.pool.Get()
	defer c.Close()

	var key string
	var err error
	prefix := s.typeName(v) + ":"

	// Using transactions to execute HGETALL in a pipeline.
	// Mark the start of a transaction block.
	// Subsequent commands will be queued for atomic execution.
	c.Send("MULTI")
	for y := 0; y < v.Len(); y++ {
		if key = v.Index(y).Addr().MethodByName("Key").Call(nil)[0].String(); len(key) == 0 {
			return store.ErrEmptyKey
		}
		// Send writes the command to the connection's output buffer.
		if err = c.Send("HGETALL", prefix+key); err != nil {
			return err
		}
	}
	// Flush flushes the connection's output buffer to the server
	if err = c.Flush(); err != nil {
		return err
	}
	// Execute all previously queued commands
	// in a transaction and restores the connection
	// state to normal
	reply, err := c.Do("EXEC")
	if err != nil {
		return err
	}

	replyValue := reflect.ValueOf(reply)
	var values []interface{}
	// Reply is a two dimentional array of interfaces. Iterate over the first
	// dimension and scan each slice into destination interface type
	for y := 0; y < replyValue.Len(); y++ {
		itemPtrV := reflect.New(v.Type().Elem())
		if values, err = driver.Values(replyValue.Index(y).Interface(), nil); err != nil {
			return err
		}
		driver.ScanStruct(values, itemPtrV.Interface())
		v.Index(y).Set(itemPtrV.Elem())
	}
	return nil
}
Example #2
0
func TestWrite(t *testing.T) {
	s := &TestR{
		ID:         uuid.New(),
		Field:      "value",
		FieldInt:   10,
		FieldFloat: 1.234,
		FieldBool:  true,
		FieldUint:  1,
	}

	db := testStore(t)

	if err := db.Write(s); err != nil {
		t.Fatal("err", err)
	}

	if len(s.Key()) == 0 {
		t.Fatalf("key is emtpy %#v", s)
	}

	cfg, err := NewConfig(testRedisURL)
	if err != nil {
		t.Fatal(err)
	}

	pool := NewPool(cfg)
	c := pool.Get()
	defer c.Close()
	reply, err := driver.Values(c.Do("HGETALL", testNs+":TestR:"+s.Key()))
	if err != nil {
		t.Fatal("err", err)
	}

	got := &TestR{}

	if err := driver.ScanStruct(reply, got); err != nil {
		t.Fatal("err", err)
	}

	if !reflect.DeepEqual(s, got) {
		t.Fatal("expected:", s, " got:", got)
	}
}
Example #3
0
// Read reads the item from redis store and copies the values to item
// It Returns store.ErrKeyNotFound when no values are found for the key provided
// and store.ErrKeyMissing when key is not provided. Unmarshalling id done using
// driver provided redis.ScanStruct
func (s *Store) Read(i store.Item) error {
	c := s.pool.Get()
	defer c.Close()

	value := reflect.ValueOf(i).Elem()
	if len(i.Key()) == 0 {
		return store.ErrEmptyKey
	}
	ri := &Item{
		key:    i.Key(),
		prefix: value.Type().Name(),
	}
	reply, err := driver.Values(c.Do("HGETALL", ri.Key()))
	if err != nil {
		return err
	}
	if len(reply) == 0 {
		return store.ErrKeyNotFound
	}
	if err := driver.ScanStruct(reply, i); err != nil {
		return err
	}
	return nil
}