From 63f1f39c40e3a025b6ce879e2d032ed430c09e03 Mon Sep 17 00:00:00 2001 From: kevin Date: Wed, 30 Sep 2020 22:25:47 +0800 Subject: [PATCH] fix int64 primary key problem --- core/stores/sqlc/cachedsql.go | 14 ++++++++++ core/stores/sqlc/cachedsql_test.go | 43 ++++++++++++++++++++++++++++++ 2 files changed, 57 insertions(+) diff --git a/core/stores/sqlc/cachedsql.go b/core/stores/sqlc/cachedsql.go index b6dc9992..90df59ff 100644 --- a/core/stores/sqlc/cachedsql.go +++ b/core/stores/sqlc/cachedsql.go @@ -82,6 +82,7 @@ func (cc CachedConn) QueryRowIndex(v interface{}, key string, keyer func(primary indexQuery IndexQueryFn, primaryQuery PrimaryQueryFn) error { var primaryKey interface{} var found bool + keyer = floatKeyer(keyer) if err := cc.cache.TakeWithExpire(&primaryKey, key, func(val interface{}, expire time.Duration) (err error) { primaryKey, err = indexQuery(cc.db, v) if err != nil { @@ -119,3 +120,16 @@ func (cc CachedConn) SetCache(key string, v interface{}) error { func (cc CachedConn) Transact(fn func(sqlx.Session) error) error { return cc.db.Transact(fn) } + +func floatKeyer(fn func(interface{}) string) func(interface{}) string { + return func(primary interface{}) string { + switch v := primary.(type) { + case float32: + return fn(int64(v)) + case float64: + return fn(int64(v)) + default: + return fn(primary) + } + } +} diff --git a/core/stores/sqlc/cachedsql_test.go b/core/stores/sqlc/cachedsql_test.go index e825d6c9..e94dca0d 100644 --- a/core/stores/sqlc/cachedsql_test.go +++ b/core/stores/sqlc/cachedsql_test.go @@ -446,6 +446,45 @@ func TestCachedConnTransact(t *testing.T) { assert.True(t, conn.transactValue) } +func TestQueryRowNoCache(t *testing.T) { + s, err := miniredis.Run() + if err != nil { + t.Error(err) + } + + const ( + key = "user" + value = "any" + ) + var user string + var ran bool + r := redis.NewRedis(s.Addr(), redis.NodeType) + conn := dummySqlConn{queryRow: func(v interface{}, q string, args ...interface{}) error { + user = value + ran = true + return nil + }} + c := NewNodeConn(&conn, r, cache.WithExpiry(time.Second*30)) + err = c.QueryRowNoCache(&user, key) + assert.Nil(t, err) + assert.Equal(t, value, user) + assert.True(t, ran) +} + +func TestFloatKeyer(t *testing.T) { + primaries := []interface{}{ + float32(1), + float64(1), + } + + for _, primary := range primaries { + val := floatKeyer(func(i interface{}) string { + return fmt.Sprint(i) + })(primary) + assert.Equal(t, "1", val) + } +} + func resetStats() { atomic.StoreUint64(&stats.Total, 0) atomic.StoreUint64(&stats.Hit, 0) @@ -454,6 +493,7 @@ func resetStats() { } type dummySqlConn struct { + queryRow func(interface{}, string, ...interface{}) error } func (d dummySqlConn) Exec(query string, args ...interface{}) (sql.Result, error) { @@ -465,6 +505,9 @@ func (d dummySqlConn) Prepare(query string) (sqlx.StmtSession, error) { } func (d dummySqlConn) QueryRow(v interface{}, query string, args ...interface{}) error { + if d.queryRow != nil { + return d.queryRow(v, query, args...) + } return nil }