diff --git a/scylladb/go.mod b/scylladb/go.mod index 3a16717b..f2941aac 100644 --- a/scylladb/go.mod +++ b/scylladb/go.mod @@ -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 diff --git a/scylladb/go.sum b/scylladb/go.sum index 9210db9b..c650fc08 100644 --- a/scylladb/go.sum +++ b/scylladb/go.sum @@ -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= diff --git a/scylladb/scylladb.go b/scylladb/scylladb.go index 6e6c4be4..4be0142a 100644 --- a/scylladb/scylladb.go +++ b/scylladb/scylladb.go @@ -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() } diff --git a/scylladb/scylladb_test.go b/scylladb/scylladb_test.go index 694d8d17..470c66fc 100644 --- a/scylladb/scylladb_test.go +++ b/scylladb/scylladb_test.go @@ -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") + key = "john" + 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)