mirror of
https://github.com/gofiber/storage.git
synced 2025-10-07 09:31:44 +08:00
Updated set to use default scylladb ttl, updated tests
This commit is contained in:
@@ -2,17 +2,18 @@ module github.com/gofiber/storage/scylladb
|
||||
|
||||
go 1.20
|
||||
|
||||
replace github.com/gocql/gocql => github.com/scylladb/gocql v1.11.1
|
||||
|
||||
require (
|
||||
github.com/gocql/gocql v1.6.0
|
||||
github.com/stretchr/testify v1.3.0
|
||||
github.com/stretchr/testify v1.8.4
|
||||
)
|
||||
|
||||
require (
|
||||
github.com/davecgh/go-spew v1.1.1 // indirect
|
||||
github.com/golang/snappy v0.0.3 // indirect
|
||||
github.com/golang/snappy v0.0.4 // indirect
|
||||
github.com/hailocab/go-hostpool v0.0.0-20160125115350-e80d13ce29ed // indirect
|
||||
github.com/pmezard/go-difflib v1.0.0 // indirect
|
||||
gopkg.in/inf.v0 v0.9.1 // indirect
|
||||
gopkg.in/yaml.v3 v3.0.1 // indirect
|
||||
)
|
||||
|
||||
replace github.com/gocql/gocql => github.com/scylladb/gocql v1.11.1
|
||||
|
@@ -5,8 +5,9 @@ github.com/bmizerany/assert v0.0.0-20160611221934-b7ed37b82869/go.mod h1:Ekp36dR
|
||||
github.com/davecgh/go-spew v1.1.0/go.mod h1:J7Y8YcW2NihsgmVo/mv3lAwl/skON4iLHjSsI+c5H38=
|
||||
github.com/davecgh/go-spew v1.1.1 h1:vj9j/u1bqnvCEfJOwUhtlOARqs3+rkHYY13jYWTU97c=
|
||||
github.com/davecgh/go-spew v1.1.1/go.mod h1:J7Y8YcW2NihsgmVo/mv3lAwl/skON4iLHjSsI+c5H38=
|
||||
github.com/golang/snappy v0.0.3 h1:fHPg5GQYlCeLIPB9BZqMVR5nR9A+IM5zcgeTdjMYmLA=
|
||||
github.com/golang/snappy v0.0.3/go.mod h1:/XxbfmMg8lxefKM7IXC3fBNl/7bRcc72aCRzEWrmP2Q=
|
||||
github.com/golang/snappy v0.0.4 h1:yAGX7huGHXlcLOEtBnF4w7FQwA26wojNCwOYAEhLjQM=
|
||||
github.com/golang/snappy v0.0.4/go.mod h1:/XxbfmMg8lxefKM7IXC3fBNl/7bRcc72aCRzEWrmP2Q=
|
||||
github.com/google/go-cmp v0.4.0 h1:xsAVV57WRhGj6kEIi8ReJzQlHHqcBYCElAvkovg3B/4=
|
||||
github.com/google/go-cmp v0.4.0/go.mod h1:v8dTdLbMG2kIc/vJvl+f65V22dbkXbowE6jgT/gNBxE=
|
||||
github.com/hailocab/go-hostpool v0.0.0-20160125115350-e80d13ce29ed h1:5upAirOpQc1Q53c0bnx2ufif5kANL7bfZWcc6VJWJd8=
|
||||
@@ -21,8 +22,9 @@ github.com/pmezard/go-difflib v1.0.0/go.mod h1:iKH77koFhYxTK1pcRnkKkqfTogsbg7gZN
|
||||
github.com/scylladb/gocql v1.11.1 h1:AlIPHHZf2l0Cbj8wGjfELspaGfnd4meGj9sPQnr5dn8=
|
||||
github.com/scylladb/gocql v1.11.1/go.mod h1:ZLEJ0EVE5JhmtxIW2stgHq/v1P4fWap0qyyXSKyV8K0=
|
||||
github.com/stretchr/objx v0.1.0/go.mod h1:HFkY916IF+rwdDfMAkV7OtwuqBVzrE8GR6GFx+wExME=
|
||||
github.com/stretchr/testify v1.3.0 h1:TivCn/peBQ7UY8ooIcPgZFpTNSz0Q2U6UrFlUfqbe0Q=
|
||||
github.com/stretchr/testify v1.3.0/go.mod h1:M5WIy9Dh21IEIfnGCwXGc5bZfKNJtfHm1UVUgZn+9EI=
|
||||
github.com/stretchr/testify v1.8.4 h1:CcVxjf3Q8PM0mHUKJCdn+eZZtm5yQwehR5yeSVQQcUk=
|
||||
github.com/stretchr/testify v1.8.4/go.mod h1:sz/lmYIOXD/1dqDmKjjqLyZ2RngseejIcXlSw2iwfAo=
|
||||
golang.org/x/net v0.0.0-20220526153639-5463443f8c37 h1:lUkvobShwKsOesNfWWlCS5q7fnbG1MEliIzwu886fn8=
|
||||
golang.org/x/net v0.0.0-20220526153639-5463443f8c37/go.mod h1:XRhObCWvk6IyKnWLug+ECip1KBveYUHfp+8e9klMJ9c=
|
||||
golang.org/x/sys v0.0.0-20210615035016-665e8c7367d1/go.mod h1:oPkhp1MJrh7nUepCBck5+mAzfO9JrbApNNgaTdGDITg=
|
||||
@@ -31,10 +33,13 @@ golang.org/x/term v0.0.0-20210927222741-03fcf44c2211/go.mod h1:jbD1KX2456YbFQfuX
|
||||
golang.org/x/text v0.3.7/go.mod h1:u+2+/6zg+i71rQMx5EYifcz6MCKuco9NR6JIITiCfzQ=
|
||||
golang.org/x/tools v0.0.0-20180917221912-90fa682c2a6e/go.mod h1:n7NCudcB/nEzxVGmLbDWY5pfWTLqBcC2KZ6jyYvM4mQ=
|
||||
golang.org/x/xerrors v0.0.0-20191204190536-9bdfabe68543/go.mod h1:I/5z698sn9Ka8TeJc9MKroUUfqBBauWjQqLJ2OPfmY0=
|
||||
gopkg.in/check.v1 v0.0.0-20161208181325-20d25e280405 h1:yhCVgyC4o1eVCa2tZl7eS0r+SDo693bJlVdllGtEeKM=
|
||||
gopkg.in/check.v1 v0.0.0-20161208181325-20d25e280405/go.mod h1:Co6ibVJAznAaIkqp8huTwlJQCZ016jof/cbN4VW5Yz0=
|
||||
gopkg.in/inf.v0 v0.9.1 h1:73M5CoZyi3ZLMOyDlQh031Cx6N9NDJ2Vvfl76EDAgDc=
|
||||
gopkg.in/inf.v0 v0.9.1/go.mod h1:cWUDdTG/fYaXco+Dcufb5Vnc6Gp2YChqWtbxRZE0mXw=
|
||||
gopkg.in/yaml.v2 v2.4.0 h1:D8xgwECY7CYvx+Y2n4sBz93Jn9JRvxdiyyo8CTfuKaY=
|
||||
gopkg.in/yaml.v2 v2.4.0/go.mod h1:RDklbk79AGWmwhnvt/jBztapEOGDOx6ZbXqjP6csGnQ=
|
||||
gopkg.in/yaml.v3 v3.0.1 h1:fxVm/GzAzEWqLHuvctI91KS9hhNmmWOoWu0XTYJS7CA=
|
||||
gopkg.in/yaml.v3 v3.0.1/go.mod h1:K4uyk7z7BCEPqu6E+C64Yfv1cQ7kz7rIZviUmN+EgEM=
|
||||
sigs.k8s.io/yaml v1.3.0 h1:a2VclLzOGrwOHDiV8EfBGhvjHvP46CtW5j6POvhYGGo=
|
||||
sigs.k8s.io/yaml v1.3.0/go.mod h1:GeOyir5tyXNByN85N/dRIT9es5UQNerPYEKK56eTBm8=
|
||||
|
@@ -19,12 +19,12 @@ type Storage struct {
|
||||
}
|
||||
|
||||
var (
|
||||
checkSchemaMsg = "the `data` row has an incorrect data type. " +
|
||||
checkSchemaMsg = "the `value` row has an incorrect data type. " +
|
||||
"The message should be BLOB, but it is instead %s. This could lead to encoding-related issues if the database is not migrated (refer to https://github.com/gofiber/storage/blob/main/MIGRATE.md)"
|
||||
createKeyspaceQuery = "CREATE KEYSPACE IF NOT EXISTS %s WITH replication = {'class': 'SimpleStrategy', 'replication_factor': 1};"
|
||||
dropQuery = `DROP TABLE IF EXISTS %s.%s;`
|
||||
createTableQuery = `CREATE TABLE IF NOT EXISTS %s.%s (id TEXT PRIMARY KEY, data BLOB, value BIGINT)`
|
||||
checkSchemaQuery = `SELECT type FROM system_schema.columns WHERE keyspace_name = '%s' AND table_name = '%s' AND column_name = 'data';`
|
||||
createTableQuery = `CREATE TABLE IF NOT EXISTS %s.%s (key TEXT PRIMARY KEY, value BLOB)`
|
||||
checkSchemaQuery = `SELECT type FROM system_schema.columns WHERE keyspace_name = '%s' AND table_name = '%s' AND column_name = 'value';`
|
||||
keyspaceMsg = `Keyspace cannot be empty.`
|
||||
)
|
||||
|
||||
@@ -87,9 +87,9 @@ func New(config ...Config) *Storage {
|
||||
store := &Storage{
|
||||
session: session,
|
||||
tableName: cfg.Table,
|
||||
selectQuery: fmt.Sprintf("SELECT data, value FROM %s.%s WHERE id = ?", cfg.Keyspace, cfg.Table),
|
||||
insertQuery: fmt.Sprintf("INSERT INTO %s.%s (id, data, value) VALUES (?, ?, ?)", cfg.Keyspace, cfg.Table),
|
||||
deleteQuery: fmt.Sprintf("DELETE FROM %s.%s WHERE id = ?", cfg.Keyspace, cfg.Table),
|
||||
selectQuery: fmt.Sprintf("SELECT value FROM %s.%s WHERE key = ?", cfg.Keyspace, cfg.Table),
|
||||
insertQuery: fmt.Sprintf("INSERT INTO %s.%s (key, value) VALUES (?, ?) USING TTL ?", cfg.Keyspace, cfg.Table),
|
||||
deleteQuery: fmt.Sprintf("DELETE FROM %s.%s WHERE key = ?", cfg.Keyspace, cfg.Table),
|
||||
resetQuery: fmt.Sprintf("TRUNCATE %s.%s", cfg.Keyspace, cfg.Table),
|
||||
}
|
||||
|
||||
@@ -115,7 +115,7 @@ func (s *Storage) createTableIfNotExists(keyspace string) error {
|
||||
}
|
||||
|
||||
func (s *Storage) checkSchema(keyspace string) {
|
||||
// Check schema for data column type (should be blob)
|
||||
// Check schema for value column type (should be blob)
|
||||
var dataType string
|
||||
query := fmt.Sprintf(checkSchemaQuery, keyspace, s.tableName)
|
||||
if err := s.session.Query(query).Scan(&dataType); err != nil {
|
||||
@@ -130,25 +130,20 @@ func (s *Storage) checkSchema(keyspace string) {
|
||||
// Get retrieves a value by key
|
||||
func (s *Storage) Get(key string) ([]byte, error) {
|
||||
var value []byte
|
||||
var expiration int64
|
||||
if err := s.session.Query(s.selectQuery, key).Scan(&value, &expiration); err != nil {
|
||||
if err := s.session.Query(s.selectQuery, key).Scan(&value); err != nil {
|
||||
if errors.Is(err, gocql.ErrNotFound) {
|
||||
return nil, nil
|
||||
}
|
||||
return nil, err
|
||||
}
|
||||
// If the expiration time has already passed, then return nil
|
||||
if expiration != 0 && expiration <= time.Now().Unix() {
|
||||
return nil, nil
|
||||
}
|
||||
return value, nil
|
||||
}
|
||||
|
||||
// Set sets a value by key
|
||||
func (s *Storage) Set(key string, value []byte, expire time.Duration) error {
|
||||
var expiration int64
|
||||
var expiration int
|
||||
if expire != 0 {
|
||||
expiration = time.Now().Add(expire).Unix()
|
||||
expiration = int(expire.Round(time.Second).Seconds())
|
||||
}
|
||||
return s.session.Query(s.insertQuery, key, value, expiration).Exec()
|
||||
}
|
||||
|
@@ -14,21 +14,30 @@ func Test_Scylla_Set(t *testing.T) {
|
||||
key = "john"
|
||||
value = []byte("doe")
|
||||
)
|
||||
err := testStore.Set(key, value, time.Minute)
|
||||
err := testStore.Set(key, value, 0)
|
||||
require.NoError(t, err)
|
||||
}
|
||||
|
||||
func Test_Scylla_Set_Override(t *testing.T) {
|
||||
func Test_Scylla_Set_Override_Get(t *testing.T) {
|
||||
var (
|
||||
key = "john"
|
||||
val = []byte("doe")
|
||||
valInitial = []byte("doe")
|
||||
valOverride = []byte("doe2")
|
||||
)
|
||||
|
||||
err := testStore.Set(key, val, 0)
|
||||
err := testStore.Set(key, valInitial, 0)
|
||||
require.NoError(t, err)
|
||||
|
||||
err = testStore.Set(key, val, 0)
|
||||
result, err := testStore.Get(key)
|
||||
require.NoError(t, err)
|
||||
require.Equal(t, valInitial, result)
|
||||
|
||||
err = testStore.Set(key, valOverride, 0)
|
||||
require.NoError(t, err)
|
||||
|
||||
result, err = testStore.Get(key)
|
||||
require.NoError(t, err)
|
||||
require.Equal(t, valOverride, result)
|
||||
}
|
||||
|
||||
func Test_Scylla_Get(t *testing.T) {
|
||||
@@ -45,7 +54,7 @@ func Test_Scylla_Get(t *testing.T) {
|
||||
require.Equal(t, val, result)
|
||||
}
|
||||
|
||||
func Test_Scylla_SetGet_Expiration(t *testing.T) {
|
||||
func Test_Scylla_Set_Expiration_Get(t *testing.T) {
|
||||
var (
|
||||
key = "john"
|
||||
val = []byte("doe")
|
||||
@@ -55,7 +64,7 @@ func Test_Scylla_SetGet_Expiration(t *testing.T) {
|
||||
err := testStore.Set(key, val, exp)
|
||||
require.NoError(t, err)
|
||||
|
||||
time.Sleep(1100 * time.Millisecond)
|
||||
time.Sleep(1001 * time.Millisecond)
|
||||
|
||||
result, err := testStore.Get(key)
|
||||
require.NoError(t, err)
|
||||
|
Reference in New Issue
Block a user