Skip to content
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
6 changes: 0 additions & 6 deletions state/sqlite/sqlite.go
Original file line number Diff line number Diff line change
Expand Up @@ -49,7 +49,6 @@ func newSQLiteStateStore(logger logger.Logger, dba DBAccess) *SQLiteStore {
state.FeatureETag,
state.FeatureTransactional,
state.FeatureTTL,
state.FeatureDeleteWithPrefix,
},
dbaccess: dba,
}
Expand Down Expand Up @@ -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 {
Expand Down
26 changes: 0 additions & 26 deletions state/sqlite/sqlite_dbaccess.go
Original file line number Diff line number Diff line change
Expand Up @@ -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
}

Expand Down Expand Up @@ -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
Expand Down Expand Up @@ -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) {
Expand Down
53 changes: 0 additions & 53 deletions state/sqlite/sqlite_integration_test.go
Original file line number Diff line number Diff line change
Expand Up @@ -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)
Expand Down Expand Up @@ -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(),
Expand Down
49 changes: 1 addition & 48 deletions state/sqlite/sqlite_migrations.go
Original file line number Diff line number Diff line change
Expand Up @@ -16,47 +16,18 @@ 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 {
StateTableName string
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{
Expand Down Expand Up @@ -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
},
},
)
})
}
19 changes: 0 additions & 19 deletions state/sqlite/sqlite_test.go
Original file line number Diff line number Diff line change
Expand Up @@ -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()
Expand Down Expand Up @@ -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
}
Expand Down Expand Up @@ -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)
Expand Down
Binary file modified tests/certification/state/sqlite/artifacts/readonly.db
Binary file not shown.
2 changes: 1 addition & 1 deletion tests/certification/state/sqlite/sqlite_test.go
Original file line number Diff line number Diff line change
Expand Up @@ -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) {
Expand Down
2 changes: 1 addition & 1 deletion tests/config/state/tests.yml
Original file line number Diff line number Diff line change
Expand Up @@ -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
Expand Down