Skip to content

Commit fdd78b5

Browse files
authored
Merge branch 'main' into 3318-RavenDB-state-store-new
2 parents 1f504d5 + ff10bea commit fdd78b5

File tree

4 files changed

+225
-11
lines changed

4 files changed

+225
-11
lines changed

common/proto/state/sqlserver/test.pb.go

Lines changed: 162 additions & 0 deletions
Some generated files are not rendered by default. Learn more about customizing how changed files appear on GitHub.
Lines changed: 10 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,10 @@
1+
syntax = "proto3";
2+
3+
option go_package = "github.com/dapr/components-contrib/common/proto/state/sqlserver";
4+
5+
import "google/protobuf/timestamp.proto";
6+
7+
message TestEvent {
8+
int32 eventId = 1;
9+
google.protobuf.Timestamp timestamp = 2;
10+
}

state/sqlserver/sqlserver.go

Lines changed: 25 additions & 9 deletions
Original file line numberDiff line numberDiff line change
@@ -16,6 +16,7 @@ package sqlserver
1616
import (
1717
"context"
1818
"database/sql"
19+
"encoding/base64"
1920
"encoding/hex"
2021
"encoding/json"
2122
"errors"
@@ -287,8 +288,15 @@ func (s *SQLServer) Get(ctx context.Context, req *state.GetRequest) (*state.GetR
287288
}
288289
}
289290

291+
bytes, err := base64.StdEncoding.DecodeString(data)
292+
if err != nil {
293+
s.logger.
294+
WithFields(map[string]any{"error": err}).
295+
Debug("error decoding base64 data. Fallback to []byte")
296+
bytes = []byte(data)
297+
}
290298
return &state.GetResponse{
291-
Data: []byte(data),
299+
Data: bytes,
292300
ETag: ptr.Of(etag),
293301
Metadata: metadata,
294302
}, nil
@@ -305,16 +313,23 @@ type dbExecutor interface {
305313
}
306314

307315
func (s *SQLServer) executeSet(ctx context.Context, db dbExecutor, req *state.SetRequest) error {
308-
var err error
309-
var bytes []byte
310-
bytes, err = utils.Marshal(req.Value, json.Marshal)
311-
if err != nil {
312-
return err
316+
var reqValue string
317+
318+
bytes, ok := req.Value.([]byte)
319+
if !ok {
320+
bt, err := json.Marshal(req.Value)
321+
if err != nil {
322+
return err
323+
}
324+
reqValue = string(bt)
325+
} else {
326+
reqValue = base64.StdEncoding.EncodeToString(bytes)
313327
}
328+
314329
etag := sql.Named(rowVersionColumnName, nil)
315330
if req.HasETag() {
316331
var b []byte
317-
b, err = hex.DecodeString(*req.ETag)
332+
b, err := hex.DecodeString(*req.ETag)
318333
if err != nil {
319334
return state.NewETagError(state.ETagInvalid, err)
320335
}
@@ -327,13 +342,14 @@ func (s *SQLServer) executeSet(ctx context.Context, db dbExecutor, req *state.Se
327342
}
328343

329344
var res sql.Result
345+
var err error
330346
if req.Options.Concurrency == state.FirstWrite {
331347
res, err = db.ExecContext(ctx, s.upsertCommand, sql.Named(keyColumnName, req.Key),
332-
sql.Named("Data", string(bytes)), etag,
348+
sql.Named("Data", reqValue), etag,
333349
sql.Named("FirstWrite", 1), sql.Named("TTL", ttl))
334350
} else {
335351
res, err = db.ExecContext(ctx, s.upsertCommand, sql.Named(keyColumnName, req.Key),
336-
sql.Named("Data", string(bytes)), etag,
352+
sql.Named("Data", reqValue), etag,
337353
sql.Named("FirstWrite", 0), sql.Named("TTL", ttl))
338354
}
339355

state/sqlserver/sqlserver_integration_test.go

Lines changed: 28 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -30,10 +30,12 @@ import (
3030
"testing"
3131
"time"
3232

33-
uuid "github.com/google/uuid"
33+
"github.com/google/uuid"
3434
"github.com/stretchr/testify/assert"
3535
"github.com/stretchr/testify/require"
36+
"google.golang.org/protobuf/proto"
3637

38+
"github.com/dapr/components-contrib/common/proto/state/sqlserver"
3739
"github.com/dapr/components-contrib/metadata"
3840
"github.com/dapr/components-contrib/state"
3941
"github.com/dapr/kit/logger"
@@ -42,7 +44,7 @@ import (
4244
const (
4345
// connectionStringEnvKey defines the key containing the integration test connection string
4446
// To use docker, server=localhost;user id=sa;password=Pass@Word1;port=1433;
45-
// To use Azure SQL, server=<your-db-server-name>.database.windows.net;user id=<your-db-user>;port=1433;password=<your-password>;database=dapr_test;.
47+
// To use Azure SQL, server=<your-db-server-name>.database.windows.net;User id=<your-db-user>;port=1433;password=<your-password>;database=dapr_test;.
4648
connectionStringEnvKey = "DAPR_TEST_SQL_CONNSTRING"
4749
usersTableName = "Users"
4850
beverageTea = "tea"
@@ -77,6 +79,7 @@ func TestIntegrationCases(t *testing.T) {
7779
t.Run("Multi operations", testMultiOperations)
7880
t.Run("Insert and Update Set Record Dates", testInsertAndUpdateSetRecordDates)
7981
t.Run("Multiple initializations", testMultipleInitializations)
82+
t.Run("Should preserve byte data when not base64 encoded", testNonBase64ByteData)
8083

8184
// Run concurrent set tests 10 times
8285
const executions = 10
@@ -112,6 +115,9 @@ func createMetadata(schema string, kt KeyType, indexedProperties string) state.M
112115

113116
// Ensure the database is running
114117
// For docker, use: docker run --name sqlserver -e "ACCEPT_EULA=Y" -e "SA_PASSWORD=Pass@Word1" -p 1433:1433 -d mcr.microsoft.com/mssql/server:2019-GA-ubuntu-16.04.
118+
// For azure-sql-edge use:
119+
// docker volume create sqlvolume
120+
// docker run --name sqlserver -e "ACCEPT_EULA=Y" -e "MSSQL_SA_PASSWORD=Pass@Word1" -e "MSSQL_PID=Developer" -e "MSSQL_AGENT_ENABLED=TRUE" -e "MSSQL_COLLATION=SQL_Latin1_General_CP1_CI_AS" -e "MSSQL_LCID=1033" -p 1433:1433 -v sqlvolume:/var/opt/mssql -d mcr.microsoft.com/azure-sql-edge:latest
115121
func getTestStore(t *testing.T, indexedProperties string) *SQLServer {
116122
return getTestStoreWithKeyType(t, StringKeyType, indexedProperties)
117123
}
@@ -597,3 +603,23 @@ func testMultipleInitializations(t *testing.T) {
597603
})
598604
}
599605
}
606+
607+
func testNonBase64ByteData(t *testing.T) {
608+
t.Run("Set And Get", func(t *testing.T) {
609+
store := getTestStore(t, "")
610+
request := &sqlserver.TestEvent{
611+
EventId: -1,
612+
}
613+
requestBytes, err := proto.Marshal(request)
614+
require.NoError(t, err)
615+
require.NoError(t, store.Set(t.Context(), &state.SetRequest{Key: "1", Value: requestBytes}))
616+
resp, err := store.Get(t.Context(), &state.GetRequest{Key: "1"})
617+
require.NoError(t, err)
618+
619+
response := &sqlserver.TestEvent{}
620+
err = proto.Unmarshal(resp.Data, response)
621+
require.NoError(t, err)
622+
623+
assert.EqualValues(t, request.GetEventId(), response.GetEventId())
624+
})
625+
}

0 commit comments

Comments
 (0)