diff --git a/README.md b/README.md deleted file mode 100644 index 10753b6..0000000 --- a/README.md +++ /dev/null @@ -1,3 +0,0 @@ -# redis - -redis操作 \ No newline at end of file diff --git a/conn.go b/conn.go index 0bf113f..60a93af 100644 --- a/conn.go +++ b/conn.go @@ -4,98 +4,11 @@ import ( redisdb "github.com/gomodule/redigo/redis" ) -// 定义redis链接池 -var pool *redisdb.Pool - -// 初始化redis链接池 -func init() { - pool = &redisdb.Pool{ - MaxIdle: 500, /*最大的空闲连接数*/ - MaxActive: 10000, /*最大的激活连接数*/ - Dial: conn, - } +//取值 +func GetConn() redisdb.Conn { + return Pool.Get() } -func conn() (redisdb.Conn, error) { - c, err := redisdb.Dial("tcp", "127.0.0.1:6379") - if err != nil { - return nil, err - } - return c, nil +func CloseConn(conn redisdb.Conn) error { + return conn.Close() } - -// // 向key的hash中添加元素field的值 -// func HashSet(key, field string, data interface{}) { -// err := client.HSet(key, field, data) -// if err != nil { -// logger.Error("Redis HSet Error:", err) -// } -// } - -// // 批量向key的hash添加对应元素field的值 -// func BatchHashSet(key string, fields map[string]interface{}) string { -// val, err := client.HMSet(key, fields).Result() -// if err != nil { -// logger.Error("Redis HMSet Error:", err) -// } -// return val -// } - -// // 通过key获取hash的元素值 -// func HashGet(key, field string) string { -// result := "" -// val, err := client.HGet(key, field).Result() -// if err == redis.Nil { -// logger.Debug("Key Doesn't Exists:", field) -// return result -// } else if err != nil { -// logger.Error("Redis HGet Error:", err) -// return result -// } -// return val -// } - -// // 批量获取key的hash中对应多元素值 -// func BatchHashGet(key string, fields ...string) map[string]interface{} { -// resMap := make(map[string]interface{}) -// for _, field := range fields { -// var result interface{} -// val, err := client.HGet(key, fmt.Sprintf("%s", field)).Result() -// if err == redis.Nil { -// logger.Debug("Key Doesn't Exists:", field) -// resMap[field] = result -// } else if err != nil { -// logger.Error("Redis HMGet Error:", err) -// resMap[field] = result -// } -// if val != "" { -// resMap[field] = val -// } else { -// resMap[field] = result -// } -// } -// return resMap -// } - -// // 获取自增唯一ID -// func Incr(key string) int { -// val, err := client.Incr(key).Result() -// if err != nil { -// logger.Error("Redis Incr Error:", err) -// } -// return int(val) -// } - -// // 添加集合数据 -// func SetAdd(key, val string) { -// client.SAdd(key, val) -// } - -// // 从集合中获取数据 -// func SetGet(key string) []string { -// val, err := client.SMembers(key).Result() -// if err != nil { -// logger.Error("Redis SMembers Error:", err) -// } -// return val -// } diff --git a/conn_test.go b/conn_test.go deleted file mode 100644 index e906d02..0000000 --- a/conn_test.go +++ /dev/null @@ -1,18 +0,0 @@ -package redis - -import ( - "testing" -) - -func Test_SetAdd(t *testing.T) { - - reply, err := Set(123, "不知道433ee4") - - t.Log(reply) - t.Log(err) - - ret, err := Get("123") - - t.Log(ret) - t.Log(err) -} diff --git a/expire.go b/expire.go new file mode 100644 index 0000000..1529dc2 --- /dev/null +++ b/expire.go @@ -0,0 +1,22 @@ +package redis + +import ( + redisdb "github.com/gomodule/redigo/redis" +) + +/** + * 设置有效期 + */ +func SetExpire(key string, expire int64) (int64, error) { + c := GetConn() + var err error + var reply interface{} + reply, err = c.Do("expire", key, expire) + + CloseConn(c) + + if err != nil { + return 0, err + } + return redisdb.Int64(reply, err) +} diff --git a/go.mod b/go.mod index 0ca04ce..9dc3ce4 100644 --- a/go.mod +++ b/go.mod @@ -1,5 +1,9 @@ -module git.tetele.net/tgo/redis +module git.tetele.net/yueheng/redis -go 1.14 +go 1.17 -require github.com/gomodule/redigo v2.0.0+incompatible // indirect +require ( + git.tetele.net/tgo/conf v0.47.0 + git.tetele.net/tgo/helper v0.3.1 + github.com/gomodule/redigo v1.8.8 +) diff --git a/go.sum b/go.sum index 4c1e172..1bb3c77 100644 --- a/go.sum +++ b/go.sum @@ -1,3 +1,16 @@ -github.com/gomodule/redigo v1.7.0 h1:ZKld1VOtsGhAe37E7wMxEDgAlGM5dvFY+DiOhSkhP9Y= -github.com/gomodule/redigo v2.0.0+incompatible h1:K/R+8tc58AaqLkqG2Ol3Qk+DR/TlNuhuh457pBFPtt0= -github.com/gomodule/redigo v2.0.0+incompatible/go.mod h1:B4C85qUVwatsJoIUNIfCRsp7qO0iAmpGFZ4EELWSbC4= +git.tetele.net/tgo/conf v0.47.0 h1:2nGvXjyFV6gO7BPliG4lwERP/bgTOeSJpUv/I2ALGPg= +git.tetele.net/tgo/conf v0.47.0/go.mod h1:AWVIBEDE5dtotthUgR0SWaR2Qa6/f+O5WQ3s7Tj8q7A= +git.tetele.net/tgo/helper v0.3.1 h1:5+6xK6nr2BB1A0XVKrrA8R/GW0y3aUuKUIcz3zgAwZo= +git.tetele.net/tgo/helper v0.3.1/go.mod h1:89mQwyfqZ+t8YXiVwzSxA70gLlUNqoZGDEUxvV46jXk= +github.com/davecgh/go-spew v1.1.0 h1:ZDRjVQ15GmhC3fiQ8ni8+OwkZQO4DARzQgrnXU1Liz8= +github.com/davecgh/go-spew v1.1.0/go.mod h1:J7Y8YcW2NihsgmVo/mv3lAwl/skON4iLHjSsI+c5H38= +github.com/gomodule/redigo v1.8.8 h1:f6cXq6RRfiyrOJEV7p3JhLDlmawGBVBBP1MggY8Mo4E= +github.com/gomodule/redigo v1.8.8/go.mod h1:7ArFNvsTjH8GMMzB4uy1snslv2BwmginuMs06a1uzZE= +github.com/pmezard/go-difflib v1.0.0 h1:4DBwDE0NGyQoBHbLQYPwSUPoCMWR5BEzIk/f1lZbAQM= +github.com/pmezard/go-difflib v1.0.0/go.mod h1:iKH77koFhYxTK1pcRnkKkqfTogsbg7gZNVY4sRDYZ/4= +github.com/stretchr/objx v0.1.0/go.mod h1:HFkY916IF+rwdDfMAkV7OtwuqBVzrE8GR6GFx+wExME= +github.com/stretchr/testify v1.7.0 h1:nwc3DEeHmmLAfoZucVR881uASk0Mfjw8xYJ99tb5CcY= +github.com/stretchr/testify v1.7.0/go.mod h1:6Fq8oRcR53rry900zMqJjRRixrwX3KX962/h/Wwjteg= +gopkg.in/check.v1 v0.0.0-20161208181325-20d25e280405/go.mod h1:Co6ibVJAznAaIkqp8huTwlJQCZ016jof/cbN4VW5Yz0= +gopkg.in/yaml.v3 v3.0.0-20200313102051-9f266ea9e77c h1:dUUwHk2QECo/6vqA44rthZ8ie2QXMNeKRTHCNY2nXvo= +gopkg.in/yaml.v3 v3.0.0-20200313102051-9f266ea9e77c/go.mod h1:K4uyk7z7BCEPqu6E+C64Yfv1cQ7kz7rIZviUmN+EgEM= diff --git a/hash.go b/hash.go index 6a53f5e..54fb393 100644 --- a/hash.go +++ b/hash.go @@ -1,74 +1,98 @@ package redis import ( - // "errors" - redisdb "github.com/gomodule/redigo/redis" ) //hash取值, 返回interface{} func HGet(key string, field interface{}) (interface{}, error) { - c := pool.Get() - defer c.Close() + c := GetConn() + + reply, err := c.Do("HGET", key, field) + CloseConn(c) - return c.Do("HGET", key, field) + return reply, err } //hash取值, 返回字符串 func HGetString(key string, field interface{}) (string, error) { - c := pool.Get() - defer c.Close() + c := GetConn() ret, err := c.Do("HGET", key, field) - if err != nil { - return "", err + + reply := "" + if err == nil { + reply, err = redisdb.String(ret, err) } - return redisdb.String(ret, err) + CloseConn(c) + return reply, err } //hash取值,返回接口类型 func HGetStringMap(key string, field interface{}) (map[string]string, error) { - c := pool.Get() - defer c.Close() + c := GetConn() ret, err := c.Do("HGET", key, field) - if err != nil { - return ret.(map[string]string), err + + reply := make(map[string]string) + + if err == nil { + reply, err = redisdb.StringMap(ret, err) } - return redisdb.StringMap(ret, err) + CloseConn(c) + return reply, err } //hash取值,返回[]byte func HGetBytes(key string, field interface{}) ([]byte, error) { - c := pool.Get() - defer c.Close() + c := GetConn() ret, err := c.Do("HGET", key, field) - if err != nil { - return nil, err + + reply := make([]byte, 0) + + if err == nil { + reply, err = redisdb.Bytes(ret, err) } - return redisdb.Bytes(ret, err) + CloseConn(c) + return reply, err } //hash取所有值 -func HGetAll(key string) ([][]byte, error) { - c := pool.Get() - defer c.Close() +func HGetAll(key string) ([]map[string]string, error) { + c := GetConn() ret, err := c.Do("HGETAll", key) - if err != nil { - return nil, err + + reply := make([][]byte, 0) + + if err == nil { + reply, err = redisdb.ByteSlices(ret, err) + } + + var info map[string]string + var all []map[string]string + + if len(reply) > 0 { + for key, item := range reply { + if key%2 == 0 { //只处理奇数位 + info = make(map[string]string) + info[string(item)] = string(reply[key+1]) + all = append(all, info) + } + + } } - // return ret, err - // return redisdb.MultiBulk(ret, err) - return redisdb.ByteSlices(ret, err) + + CloseConn(c) + return all, err } @@ -79,25 +103,56 @@ func HGetAll(key string) ([][]byte, error) { * value 值 * 2020/06/06 */ -func HSet(key string, field, value interface{}) (interface{}, error) { - c := pool.Get() - defer c.Close() +func HSet(key string, field, value interface{}) (int64, error) { + c := GetConn() reply, err := c.Do("HSET", key, field, value) + CloseConn(c) + + if err != nil { + return 0, err + } else { + return redisdb.Int64(reply, nil) + } + +} + +/* + * hash存值, + * key 域 + * field 名 + * value 值 + * 2020/06/06 + */ +func HIncrby(key string, field, value interface{}) (int64, error) { + c := GetConn() + + reply, err := c.Do("hincrby", key, field, value) + CloseConn(c) + + if err != nil { + return 0, err + } else { + return redisdb.Int64(reply, nil) + } - return reply, err } /* * 删除hash值 */ -func HDel(key,field string) error{ - c := pool.Get() - defer c.Close() +func HDel(key, field string) (int64, error) { + c := GetConn() + + reply, err := c.Do("HDEL", key, field) - _, err := c.Do("HDEL", key, field) + CloseConn(c) - return err + if err != nil { + return 0, err + } else { + return redisdb.Int64(reply, nil) + } } /* @@ -106,11 +161,10 @@ func HDel(key,field string) error{ * 2020/06/06 */ func HMSet(args ...interface{}) (interface{}, error) { - c := pool.Get() - defer c.Close() + c := GetConn() reply, err := c.Do("HMSET", args...) - + CloseConn(c) return reply, err } @@ -121,7 +175,27 @@ func HMSet(args ...interface{}) (interface{}, error) { * 2020/06/06 */ func HSetExpire(key string, expire int) (interface{}, error) { - c := pool.Get() - defer c.Close() - return c.Do("expire", key, expire) + c := GetConn() + reply, err := c.Do("expire", key, expire) + + CloseConn(c) + return reply, err +} + +/** + * hash键是否存在 + * key 域 + * field 名 + */ +func HExists(key, field string) (int64, error) { + c := GetConn() + + reply, err := c.Do("HEXISTS", key, field) + CloseConn(c) + + if err != nil { + return 0, err + } else { + return redisdb.Int64(reply, nil) + } } diff --git a/hash_test.go b/hash_test.go deleted file mode 100644 index 1b074d1..0000000 --- a/hash_test.go +++ /dev/null @@ -1,44 +0,0 @@ -package redis - -import ( - // "strconv" - "testing" - // "tgo/helper" -) - -func Test_HSet(t *testing.T) { - - // val := map[string]interface{}{"id": "123", "name": "这是一个测试", "dis": "xxx"} - - // reply, err := HSet("testing2", "test1", val) - - // t.Log(reply) - // t.Log(err) - - // ret, err := HGetString("testing2", "test1") - - // t.Log(ret) - // if err == nil { - // t.Log("nil", err) - // } else { - // t.Log("error:", err) - // } - - // ret2, err := HSetExpire("testing2", 200) - // t.Log(ret2) - // t.Log(err) - - ret3, err := HMSet("testing2", "test1", "test1") - t.Log(ret3) - t.Log(err) - - ret4, err := HGetAll("1000064_product") - // ret := ret4.([]interface{}) - // t.Log() - for _, val := range ret4 { - // str := strconv.FormatUint(val.([]uint64), 10) - // t.Log(helper.ToStr(val)) - t.Log(string(val)) - } - t.Log(err) -} diff --git a/init.go b/init.go new file mode 100644 index 0000000..6c4ba6a --- /dev/null +++ b/init.go @@ -0,0 +1,58 @@ +package redis + +import ( + "log" + "time" + + "git.tetele.net/tgo/conf" + redisdb "github.com/gomodule/redigo/redis" +) + +// 定义redis链接池 +var Pool *redisdb.Pool + +// func init() { +// if Pool == nil { +// RedisInit() +// } +// } + +// 初始化redis链接池 +func RedisInit(max ...int) { + + var MaxActive, MaxIdle int + if len(max) > 0 { + MaxActive = max[0] + } + if len(max) > 1 { + MaxIdle = max[1] + } + + Pool = &redisdb.Pool{ + MaxIdle: MaxIdle, /*最大的空闲连接数*/ + MaxActive: MaxActive, /*最大的激活连接数*/ + Dial: redisConn, + } +} + +func redisConn() (redisdb.Conn, error) { + + var url string = conf.REDIS_SERVER + if url == "" { + url = "127.0.0.1:6379" + } + + dbOption := redisdb.DialDatabase(0) + pwOption := redisdb.DialPassword("") + // **重要** 设置读写超时 + readTimeout := redisdb.DialReadTimeout(time.Second * time.Duration(2)) + writeTimeout := redisdb.DialWriteTimeout(time.Second * time.Duration(5)) + conTimeout := redisdb.DialConnectTimeout(time.Second * time.Duration(2)) + + c, err := redisdb.Dial("tcp", url, dbOption, pwOption, readTimeout, writeTimeout, conTimeout) + if err != nil { + log.Println("redis server connect failed", err) + return nil, err + } + return c, nil +} diff --git a/int.go b/int.go deleted file mode 100644 index 782563a..0000000 --- a/int.go +++ /dev/null @@ -1,17 +0,0 @@ -package redis - -func Incr(key string) (interface{}, error) { - - c := pool.Get() - defer c.Close() - - return c.Do("INCR", key) -} - -func Decr(key string) (interface{}, error) { - - c := pool.Get() - defer c.Close() - - return c.Do("DECR", key) -} diff --git a/int_test.go b/int_test.go deleted file mode 100644 index 49aa2f4..0000000 --- a/int_test.go +++ /dev/null @@ -1,13 +0,0 @@ -package redis - -import ( - "testing" -) - -func Test_Incr(t *testing.T) { - reply, err := Incr("xxx") - t.Log(reply, err) - - reply, err := Decr("xxx") - t.Log(reply, err) -} diff --git a/list.go b/list.go new file mode 100644 index 0000000..6e610b4 --- /dev/null +++ b/list.go @@ -0,0 +1,80 @@ +package redis + +import ( + redisdb "github.com/gomodule/redigo/redis" +) + +//list 尾部增加值 + +func Rpush(key string, field interface{}) (int64, error) { + c := GetConn() + + reply, err := c.Do("RPUSH", key, field) + CloseConn(c) + + if err != nil { + return 0, err + } + + return redisdb.Int64(reply, nil) +} + +//list 头部增加值 + +func Lpush(key string, field interface{}) (int64, error) { + c := GetConn() + + reply, err := c.Do("LPUSH", key, field) + CloseConn(c) + + if err != nil { + return 0, err + } + + return redisdb.Int64(reply, nil) +} + +//list 长度 + +func Llen(key string) (int64, error) { + c := GetConn() + + reply, err := c.Do("LLEN", key) + CloseConn(c) + + if err != nil { + return 0, err + } + + return redisdb.Int64(reply, nil) +} + +//list 通过索引设置列表元素的值 LSET key index value + +func Lset(key string, index int, value interface{}) (interface{}, error) { + c := GetConn() + + reply, err := c.Do("LSET", key, index, value) + CloseConn(c) + + return reply, err +} + +/* + LRANGE key start stop + 获取列表指定范围内的元素 +*/ + +func Lrange(key string, start, stop int64) ([][]byte, error) { + c := GetConn() + + ret, err := c.Do("LRANGE", key, start, stop) + + reply := make([][]byte, 0) + + if err == nil { + reply, err = redisdb.ByteSlices(ret, err) + } + CloseConn(c) + return reply, err +} diff --git a/num.go b/num.go new file mode 100644 index 0000000..c878ecb --- /dev/null +++ b/num.go @@ -0,0 +1,41 @@ +package redis + +import ( + redisdb "github.com/gomodule/redigo/redis" +) + +/** + * key增加 + */ +func Incrby(key string, value interface{}) (int64, error) { + c := GetConn() + var err error + var reply interface{} + reply, err = c.Do("INCRBY", key, value) + + CloseConn(c) + + if err != nil { + return 0, err + } + ret, err := redisdb.Int64(reply, err) + return ret, err +} + +/** + * key减 + */ +func Decrby(key string, value interface{}) (int64, error) { + c := GetConn() + var err error + var reply interface{} + reply, err = c.Do("DECRBY", key, value) + + CloseConn(c) + + if err != nil { + return 0, err + } + ret, err := redisdb.Int64(reply, err) + return ret, err +} diff --git a/set.go b/set.go new file mode 100644 index 0000000..5714dd0 --- /dev/null +++ b/set.go @@ -0,0 +1,175 @@ +package redis + +import ( + "errors" + + redisdb "github.com/gomodule/redigo/redis" +) + +/* + * 存值 + * key 域 + * value 值 + * 2021/08/31 + */ +func SAdd(key string, value interface{}) (int64, error) { + c := GetConn() + + reply, err := c.Do("SADD", key, value) + CloseConn(c) + + if err != nil { + return 0, err + } else { + return redisdb.Int64(reply, nil) + } + +} + +/* + * 删除hash值 + */ +func SRem(key, value interface{}) (int64, error) { + c := GetConn() + + reply, err := c.Do("SREM", key, value) + + CloseConn(c) + + if err != nil { + return 0, err + } else { + return redisdb.Int64(reply, nil) + } +} + +/** + * 集合键是否存在 + * key 域 + * field 名 + */ +func SIsmember(key, value interface{}) (int64, error) { + c := GetConn() + + reply, err := c.Do("SISMEMBER", key, value) + CloseConn(c) + + if err != nil { + return 0, err + } else { + return redisdb.Int64(reply, nil) + } +} + +/** + * 集合成员数量 + */ +func SCard(key interface{}) (int64, error) { + c := GetConn() + + reply, err := c.Do("SCard", key) + CloseConn(c) + + if err != nil { + return 0, err + } else { + return redisdb.Int64(reply, nil) + } +} + +//hash取值,返回[]byte + +func SMembers(key string) ([]byte, error) { + c := GetConn() + + ret, err := c.Do("SMEMBERS", key) + + reply := make([]byte, 0) + + if err == nil { + reply, err = redisdb.Bytes(ret, err) + } + CloseConn(c) + return reply, err + +} + +func ZAdd(key, score, member string) (int64, error) { + c := GetConn() + + reply, err := c.Do("ZADD", key, score, member) + CloseConn(c) + + if err != nil { + return 0, err + } else { + return redisdb.Int64(reply, nil) + } + +} + +func ZIncrBy(key, inc, member string) (int64, error) { + c := GetConn() + + reply, err := c.Do("ZINCRBY", key, inc, member) + CloseConn(c) + + if err != nil { + return 0, err + } else { + return redisdb.Int64(reply, nil) + } + +} + +func ZRange(key string, start, stop int64) ([]map[string]string, error) { + c := GetConn() + defer CloseConn(c) + values, err := redisdb.Values(c.Do("ZRANGE", key, start, stop, "WITHSCORES")) + if err != nil { + return nil, err + } + if len(values)%2 != 0 { + return nil, errors.New("redigo: ZRange expects even number of values result") + } + var l []map[string]string + for i := 0; i < len(values); i += 2 { + key, okKey := values[i].([]byte) + value, okValue := values[i+1].([]byte) + if !okKey || !okValue { + return nil, errors.New("redigo: ZRange key not a bulk string value") + } + l = append(l, map[string]string{ + "member": string(key), + "score": string(value), + }) + } + + return l, nil + +} + +func ZScan(key, field string, len int64) ([]string, error) { + c := GetConn() + defer CloseConn(c) + + zscanResult, err := redisdb.Values(c.Do("ZSCAN", key, "0", "MATCH", field, "COUNT", len)) + + if err != nil { + return nil, err + } + + var cursor int + var membersAndScores []string + var member []string + redisdb.Scan(zscanResult, &cursor, &membersAndScores) + + for i, v := range membersAndScores { + if i%2 == 0 { + member = append(member, v) + } + } + + return member, nil + +} diff --git a/string.go b/string.go index cdeb72e..2a5b1ab 100644 --- a/string.go +++ b/string.go @@ -2,16 +2,16 @@ package redis import ( "errors" - + "git.tetele.net/tgo/helper" redisdb "github.com/gomodule/redigo/redis" ) //取值 -func Get(key string) (string, error) { - c := pool.Get() - defer c.Close() - - return redisdb.String(c.Do("get", key)) +func GetString(key string) (string, error) { + c := GetConn() + str, err := redisdb.String(c.Do("get", key)) + CloseConn(c) + return str, err } /* @@ -19,59 +19,90 @@ func Get(key string) (string, error) { * args,范围(key, value)或(key, value,expire) * 2020/06/06 */ -func Set(args ...interface{}) (interface{}, error) { - c := pool.Get() - defer c.Close() +func Set(args ...interface{}) (string, error) { + c := GetConn() if len(args) < 2 { - return nil, errors.New("参数错误,至少需两个参数") + return "", errors.New("参数错误,至少需两个参数") } var err error var reply interface{} - if len(args) > 2 { + if len(args) > 2 && helper.ToInt(args[2]) > 0 { reply, err = c.Do("SET", args[0], args[1], "EX", args[2]) //设置过期时间 } else { reply, err = c.Do("SET", args[0], args[1]) } - return reply, err + + CloseConn(c) + + if err != nil { + return "", err + } + ret, err := redisdb.String(reply, err) + return ret, err } /** * 删除key */ -func Del(key string) (int,error){ - c := pool.Get() - defer c.Close() +func Del(key string) (int64, error) { + c := GetConn() var err error var reply interface{} reply, err = c.Do("DEL", key) - return redisdb.Int(reply, err) + + CloseConn(c) + + if err != nil { + return 0, err + } + ret, err := redisdb.Int64(reply, err) + return ret, err } /** * 设锁 * 2020/01/15 */ -func SetLock(args ...interface{}) (bool,error){ - c := pool.Get() - defer c.Close() +func SetNx(args ...interface{}) (int64, error) { + c := GetConn() if len(args) < 2 { - return false, errors.New("参数错误,至少需两个参数") + return 0, errors.New("参数错误,至少需两个参数") } var err error var result interface{} - if len(args) > 2 { - result, err = c.Do("SETNX", args[0], args[1], "EX", args[2]) //设置过期时间 + if len(args) > 2 && helper.ToInt(args[2]) > 0 { + result, err = c.Do("SET", args[0],args[1],"EX",args[2],"NX") //设置过期时间 } else { result, err = c.Do("SETNX", args[0], args[1]) } - if err != nil{ - return false,err + if err != nil { + return 0, err } - if result.(int) == 1{ - return true, nil - } else{ - return false, nil + CloseConn(c) + + if helper.ToStr(result) == "OK"{ + return 1, nil + } + + return 0,nil +} + +/** + * key是否存在 + */ +func Exists(key string) (int64, error) { + c := GetConn() + var err error + var reply interface{} + reply, err = c.Do("Exists", key) + + CloseConn(c) + + if err != nil { + return 0, err } + ret, err := redisdb.Int64(reply, err) + return ret, err } \ No newline at end of file diff --git a/string_test.go b/string_test.go deleted file mode 100644 index 79aa341..0000000 --- a/string_test.go +++ /dev/null @@ -1,23 +0,0 @@ -package redis - -import ( - "testing" - // "time" -) - -func Test_Get(t *testing.T) { - - reply, err := Get("siteListCache") - - t.Log(reply) - t.Log(err) -} - -func Test_Set(t *testing.T) { - - c, err := Set("test", 1111, 7200) - t.Log(c) - t.Log(err) - - p,err := pool. -} diff --git a/watch.go b/watch.go index 793b601..78cadca 100644 --- a/watch.go +++ b/watch.go @@ -2,71 +2,79 @@ package redis import ( "errors" - "time" + "strconv" redisdb "github.com/gomodule/redigo/redis" ) -type Tx struct { - conn redisdb.Conn -} - -func NewTx() (*Tx, error) { - var conn redisdb.Conn - var i int = 0 +//监视key递减 +func WatchSub(key, value string) (bool, error) { var err error - for { - if i > 100 { - break - } - conn = pool.Get() - if conn != nil { - break - } else { - err = errors.New("no conn") - } - i++ - time.Sleep(time.Microsecond * 1000) + c := GetConn() + + reply, err := c.Do("WATCH", key) + + if err != nil { + + c.Do("UNWATCH") + return false, err } - if conn != nil { - n := &Tx{conn: pool.Get()} - return n, nil - } else { - return nil, err + + reply, err = c.Do("GET", key) + + if err != nil { + c.Do("UNWATCH") + return false, err } -} -func (tx *Tx) GetInt(key string) (int, error) { + stock, err := redisdb.Int64(reply, err) - return redisdb.Int(tx.conn.Do("GET", key)) -} + if err != nil { + c.Do("UNWATCH") + return false, err + } -func (tx *Tx) Watch(key string) (interface{}, error) { + use, err := strconv.ParseInt(value, 10, 64) + if err != nil { + c.Do("UNWATCH") + return false, err + } - return tx.conn.Do("WATCH", key) -} + if stock < use { + c.Do("UNWATCH") + return false, errors.New("数量已不足") + } -func (tx *Tx) Multi() (interface{}, error) { + reply, err = c.Do("MULTI") - return tx.conn.Do("MULTI") -} + if err != nil { + c.Do("UNWATCH") + return false, err + } -func (tx *Tx) Exec() (interface{}, error) { + num := stock - use - return tx.conn.Do("Exec") -} + reply, err = c.Do("SET", key, num) -func (tx *Tx) Incr(key string) (interface{}, error) { + if err != nil { + c.Do("UNWATCH") + return false, err + } - return tx.conn.Do("INCR", key) -} + reply, err = c.Do("EXEC") -func (tx *Tx) Decr(key string) (interface{}, error) { + c.Do("UNWATCH") - return tx.conn.Do("DECR", key) -} + CloseConn(c) + + if err != nil { + return false, err + } -func (tx *Tx) Close() error { + if reply != nil { + + return true, err + } - return tx.conn.Close() + return false, err } diff --git a/watch_test.go b/watch_test.go deleted file mode 100644 index f131dc3..0000000 --- a/watch_test.go +++ /dev/null @@ -1,71 +0,0 @@ -package redis - -import ( - "strconv" - "testing" - // "time" -) - -var succ []int - -func Test_Watch(t *testing.T) { - - var key string = "tttttt" - - // var tx *Tx - var count int - - for i := 0; i < 100000; i++ { - - // t.Log(i) - - go func(i int) { - - // t.Log(i) - tx, err := NewTx() - // t.Log(tx, err) - - if err == nil { - - reply, err := tx.Watch(key) - - // t.Log("watch:", reply, err) - - count_str, err := Get(key) - - count, _ = strconv.Atoi(count_str) - - // t.Log("count:", count, err) - - reply, err = tx.Multi() - - // t.Log("Multi:", reply, err) - - if count > 0 && err == nil { - - // t.Log("start decr,", i) - - reply, err = tx.Decr(key) - - // t.Log("Decr:", reply, err) - - reply, err = tx.Exec() - - // t.Log("Exec:", exec_reply, err, i) - - if err == nil && reply != nil { - // reply, err = HSet("succ", i, i) - succ = append(succ, i) - t.Log("succ:", i, succ) - } - - } - - err = tx.Close() - // t.Log("Close:", err) - } - }(i) - } - - t.Log(succ) -}