Remove DeleteWithPrefix from SQLite for now (#3316)
Signed-off-by: ItalyPaleAle <43508+ItalyPaleAle@users.noreply.github.com>
This commit is contained in:
parent
28a3d649a3
commit
837c35a9c6
|
@ -49,7 +49,6 @@ func newSQLiteStateStore(logger logger.Logger, dba DBAccess) *SQLiteStore {
|
|||
state.FeatureETag,
|
||||
state.FeatureTransactional,
|
||||
state.FeatureTTL,
|
||||
state.FeatureDeleteWithPrefix,
|
||||
},
|
||||
dbaccess: dba,
|
||||
}
|
||||
|
@ -101,11 +100,6 @@ func (s *SQLiteStore) Multi(ctx context.Context, request *state.TransactionalSta
|
|||
return s.dbaccess.ExecuteMulti(ctx, request.Operations)
|
||||
}
|
||||
|
||||
// DeleteWithPrefix deletes objects with a prefix.
|
||||
func (s *SQLiteStore) DeleteWithPrefix(ctx context.Context, req state.DeleteWithPrefixRequest) (state.DeleteWithPrefixResponse, error) {
|
||||
return s.dbaccess.DeleteWithPrefix(ctx, req)
|
||||
}
|
||||
|
||||
// Close implements io.Closer.
|
||||
func (s *SQLiteStore) Close() error {
|
||||
if s.dbaccess != nil {
|
||||
|
|
|
@ -46,7 +46,6 @@ type DBAccess interface {
|
|||
Delete(ctx context.Context, req *state.DeleteRequest) error
|
||||
BulkGet(ctx context.Context, req []state.GetRequest) ([]state.BulkGetResponse, error)
|
||||
ExecuteMulti(ctx context.Context, reqs []state.TransactionalStateOperation) error
|
||||
DeleteWithPrefix(ctx context.Context, req state.DeleteWithPrefixRequest) (state.DeleteWithPrefixResponse, error)
|
||||
Close() error
|
||||
}
|
||||
|
||||
|
@ -80,7 +79,6 @@ func (a *sqliteDBAccess) Init(ctx context.Context, md state.Metadata) error {
|
|||
return err
|
||||
}
|
||||
|
||||
registerFuntions()
|
||||
connString, err := a.metadata.GetConnectionString(a.logger, sqlite.GetConnectionStringOpts{})
|
||||
if err != nil {
|
||||
// Already logged
|
||||
|
@ -421,30 +419,6 @@ func (a *sqliteDBAccess) Delete(ctx context.Context, req *state.DeleteRequest) e
|
|||
return a.doDelete(ctx, a.db, req)
|
||||
}
|
||||
|
||||
func (a *sqliteDBAccess) DeleteWithPrefix(ctx context.Context, req state.DeleteWithPrefixRequest) (state.DeleteWithPrefixResponse, error) {
|
||||
err := req.Validate()
|
||||
if err != nil {
|
||||
return state.DeleteWithPrefixResponse{}, err
|
||||
}
|
||||
|
||||
ctx, cancel := context.WithTimeout(ctx, a.metadata.Timeout)
|
||||
defer cancel()
|
||||
|
||||
// Concatenation is required for table name because sql.DB does not substitute parameters for table names.
|
||||
//nolint:gosec
|
||||
result, err := a.db.ExecContext(ctx, "DELETE FROM "+a.metadata.TableName+" WHERE prefix = ?", req.Prefix)
|
||||
if err != nil {
|
||||
return state.DeleteWithPrefixResponse{}, err
|
||||
}
|
||||
|
||||
rows, err := result.RowsAffected()
|
||||
if err != nil {
|
||||
return state.DeleteWithPrefixResponse{}, err
|
||||
}
|
||||
|
||||
return state.DeleteWithPrefixResponse{Count: rows}, nil
|
||||
}
|
||||
|
||||
func (a *sqliteDBAccess) ExecuteMulti(parentCtx context.Context, reqs []state.TransactionalStateOperation) error {
|
||||
// If there's only 1 operation, skip starting a transaction
|
||||
switch len(reqs) {
|
||||
|
|
|
@ -140,10 +140,6 @@ func TestSqliteIntegration(t *testing.T) {
|
|||
multiWithSetOnly(t, s)
|
||||
})
|
||||
|
||||
t.Run("Delete with Prefix (actor state)", func(t *testing.T) {
|
||||
testDeleteWithPrefix(t, s)
|
||||
})
|
||||
|
||||
t.Run("ttlExpireTime", func(t *testing.T) {
|
||||
getExpireTime(t, s)
|
||||
getBulkExpireTime(t, s)
|
||||
|
@ -614,55 +610,6 @@ func setItemWithNoKey(t *testing.T, s state.Store) {
|
|||
require.Error(t, err)
|
||||
}
|
||||
|
||||
func testDeleteWithPrefix(t *testing.T, s state.Store) {
|
||||
setReq1 := &state.SetRequest{
|
||||
Key: "mock-app-id||mock-actor-type||mock-actor-id||key0",
|
||||
}
|
||||
|
||||
setReq2 := &state.SetRequest{
|
||||
Key: "mock-app-id||mock-actor-type||mock-actor-id||key1",
|
||||
}
|
||||
|
||||
setReq3 := &state.SetRequest{
|
||||
Key: "mock-app-id||mock-actor-type||mock-actor-id||key2",
|
||||
}
|
||||
|
||||
setReq4 := &state.SetRequest{
|
||||
Key: "different-app-id||different-actor-type||different-actor-id||key0",
|
||||
}
|
||||
|
||||
delReq := state.DeleteWithPrefixRequest{
|
||||
Prefix: "mock-app-id||mock-actor-type||mock-actor-id",
|
||||
}
|
||||
|
||||
err := s.Set(context.Background(), setReq1)
|
||||
require.NoError(t, err)
|
||||
|
||||
err = s.Set(context.Background(), setReq2)
|
||||
require.NoError(t, err)
|
||||
|
||||
err = s.Set(context.Background(), setReq3)
|
||||
require.NoError(t, err)
|
||||
|
||||
err = s.Set(context.Background(), setReq4)
|
||||
require.NoError(t, err)
|
||||
|
||||
res, err := s.(state.DeleteWithPrefix).DeleteWithPrefix(context.Background(), delReq)
|
||||
require.NoError(t, err)
|
||||
assert.Equal(t, int64(3), res.Count)
|
||||
|
||||
delReq = state.DeleteWithPrefixRequest{
|
||||
Prefix: "different-app-id||different-actor-type||different-actor-id||",
|
||||
}
|
||||
res, err = s.(state.DeleteWithPrefix).DeleteWithPrefix(context.Background(), delReq)
|
||||
require.NoError(t, err)
|
||||
assert.Equal(t, int64(1), res.Count)
|
||||
|
||||
res, err = s.(state.DeleteWithPrefix).DeleteWithPrefix(context.Background(), delReq)
|
||||
require.NoError(t, err)
|
||||
assert.Equal(t, int64(0), res.Count)
|
||||
}
|
||||
|
||||
func testSetItemWithInvalidTTL(t *testing.T, s state.Store) {
|
||||
setReq := &state.SetRequest{
|
||||
Key: randomKey(),
|
||||
|
|
|
@ -16,15 +16,11 @@ package sqlite
|
|||
import (
|
||||
"context"
|
||||
"database/sql"
|
||||
"database/sql/driver"
|
||||
"fmt"
|
||||
"strings"
|
||||
|
||||
commonsql "github.com/dapr/components-contrib/common/component/sql"
|
||||
sqlitemigrations "github.com/dapr/components-contrib/common/component/sql/migrations/sqlite"
|
||||
"github.com/dapr/kit/logger"
|
||||
|
||||
sqlite3 "modernc.org/sqlite"
|
||||
)
|
||||
|
||||
type migrationOptions struct {
|
||||
|
@ -32,31 +28,6 @@ type migrationOptions struct {
|
|||
MetadataTableName string
|
||||
}
|
||||
|
||||
func registerFuntions() {
|
||||
sqlite3.RegisterDeterministicScalarFunction(
|
||||
"parse_key_prefix",
|
||||
1,
|
||||
func(ctx *sqlite3.FunctionContext, args []driver.Value) (driver.Value, error) {
|
||||
var s1 string
|
||||
switch arg0 := args[0].(type) {
|
||||
case string:
|
||||
s1 = arg0
|
||||
default:
|
||||
return "", fmt.Errorf("expected argv[0] to be text")
|
||||
}
|
||||
if len(s1) == 0 {
|
||||
return "", fmt.Errorf("cannot create prefix for empty string")
|
||||
}
|
||||
|
||||
lastIndex := strings.LastIndex(s1, "||")
|
||||
if lastIndex != -1 {
|
||||
return s1[:lastIndex+2], nil
|
||||
}
|
||||
return "", nil
|
||||
},
|
||||
)
|
||||
}
|
||||
|
||||
// Perform the required migrations
|
||||
func performMigrations(ctx context.Context, db *sql.DB, logger logger.Logger, opts migrationOptions) error {
|
||||
m := sqlitemigrations.Migrations{
|
||||
|
@ -90,23 +61,5 @@ func performMigrations(ctx context.Context, db *sql.DB, logger logger.Logger, op
|
|||
}
|
||||
return nil
|
||||
},
|
||||
// Migration 1: add the "prefix" column
|
||||
func(ctx context.Context) error {
|
||||
// Add the "prefix" column that can be used by DeleteWithPrefix
|
||||
logger.Infof("Adding 'prefix' column to table '%s'", opts.StateTableName)
|
||||
_, err := m.GetConn().ExecContext(
|
||||
ctx,
|
||||
fmt.Sprintf(
|
||||
`ALTER TABLE %[1]s ADD COLUMN prefix TEXT GENERATED ALWAYS AS (parse_key_prefix(key)) VIRTUAL;
|
||||
CREATE INDEX %[1]s_prefix_index ON %[1]s(prefix) WHERE prefix != ""`,
|
||||
opts.StateTableName,
|
||||
),
|
||||
)
|
||||
if err != nil {
|
||||
return fmt.Errorf("failed to create virtual column: %w", err)
|
||||
}
|
||||
return nil
|
||||
},
|
||||
},
|
||||
)
|
||||
})
|
||||
}
|
||||
|
|
|
@ -294,15 +294,6 @@ func TestValidMultiDeleteRequest(t *testing.T) {
|
|||
require.NoError(t, err)
|
||||
}
|
||||
|
||||
func TestValidEmptyDeleteWithPrefixRequest(t *testing.T) {
|
||||
t.Parallel()
|
||||
|
||||
ods := createSqlite(t)
|
||||
res, err := ods.DeleteWithPrefix(context.Background(), createDeleteWithPrefixRequest())
|
||||
require.NoError(t, err)
|
||||
assert.Equal(t, int64(0), res.Count)
|
||||
}
|
||||
|
||||
// Proves that the Ping method runs the ping method.
|
||||
func TestPingRunsDBAccessPing(t *testing.T) {
|
||||
t.Parallel()
|
||||
|
@ -347,10 +338,6 @@ func (m *fakeDBaccess) BulkGet(parentCtx context.Context, req []state.GetRequest
|
|||
return nil, nil
|
||||
}
|
||||
|
||||
func (m *fakeDBaccess) DeleteWithPrefix(ctx context.Context, req state.DeleteWithPrefixRequest) (state.DeleteWithPrefixResponse, error) {
|
||||
return state.DeleteWithPrefixResponse{}, nil
|
||||
}
|
||||
|
||||
func (m *fakeDBaccess) Delete(ctx context.Context, req *state.DeleteRequest) error {
|
||||
return nil
|
||||
}
|
||||
|
@ -402,12 +389,6 @@ func createDeleteRequest() state.DeleteRequest {
|
|||
}
|
||||
}
|
||||
|
||||
func createDeleteWithPrefixRequest() state.DeleteWithPrefixRequest {
|
||||
return state.DeleteWithPrefixRequest{
|
||||
Prefix: randomKey(),
|
||||
}
|
||||
}
|
||||
|
||||
func createSqliteWithFake(t *testing.T) (*SQLiteStore, *fakeDBaccess) {
|
||||
ods := createSqlite(t)
|
||||
fake := ods.dbaccess.(*fakeDBaccess)
|
||||
|
|
Binary file not shown.
|
@ -64,7 +64,7 @@ const (
|
|||
|
||||
// Update this constant if you add more migrations
|
||||
// Don't forget to also run the utility `artifacts/update_readonlydb.go` to update the read-only DB
|
||||
migrationLevel = "2"
|
||||
migrationLevel = "1"
|
||||
)
|
||||
|
||||
func TestSQLite(t *testing.T) {
|
||||
|
|
|
@ -55,7 +55,7 @@ components:
|
|||
# This component requires etags to be UUIDs
|
||||
badEtag: "e9b9e142-74b1-4a2e-8e90-3f4ffeea2e70"
|
||||
- component: sqlite
|
||||
operations: [ "transaction", "etag", "first-write", "ttl", "delete-with-prefix" ]
|
||||
operations: [ "transaction", "etag", "first-write", "ttl" ]
|
||||
- component: mysql.mysql
|
||||
operations: [ "transaction", "etag", "first-write", "ttl" ]
|
||||
- component: mysql.mariadb
|
||||
|
|
Loading…
Reference in New Issue