Skip to content
Open
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
3 changes: 3 additions & 0 deletions .github/workflows/spanner-lib-tests.yml
Original file line number Diff line number Diff line change
Expand Up @@ -145,6 +145,9 @@ jobs:
working-directory: spannerlib/wrappers/spannerlib-dotnet/spannerlib-dotnet-tests
run: |
dotnet --version
if [ "$RUNNER_OS" == "Linux" ]; then
export SKIP_SHARED_LIB_TESTS=true
fi
# Retry the tests 3 times before the step actually fails.
# We do this because the tests are executed using both the internal gRPC server and using a shared
# native library. The latter is not really supported due to an incompatibility between the .NET and Go
Expand Down
22 changes: 19 additions & 3 deletions spannerlib/api/rows.go
Original file line number Diff line number Diff line change
Expand Up @@ -70,7 +70,7 @@ func NextResultSet(ctx context.Context, poolId, connId, rowsId int64) (*spannerp
// as it allows the library to re-use the encoding buffer.
// TODO: Add an encoder function as input argument, instead of hardcoding protobuf encoding here.
func NextEncoded(ctx context.Context, poolId, connId, rowsId int64) ([]byte, error) {
_, bytes, err := next(ctx, poolId, connId, rowsId, true)
_, bytes, err := next(ctx, poolId, connId, rowsId /*marshalResult=*/, true /*resetBuffer=*/, false)
if err != nil {
return nil, err
}
Expand All @@ -79,7 +79,20 @@ func NextEncoded(ctx context.Context, poolId, connId, rowsId int64) ([]byte, err

// Next returns the next row as a protobuf ListValue.
func Next(ctx context.Context, poolId, connId, rowsId int64) (*structpb.ListValue, error) {
values, _, err := next(ctx, poolId, connId, rowsId, false)
return nextWithBufferOption(ctx, poolId, connId, rowsId /*resetBuffer=*/, true)
}

// NextBuffered returns the next row as a protobuf ListValue.
// The same buffer is used to construct the ListValue for each call. This means that this function is only
// safe to call if the result that is returned is copied into a different data structure before the next call
// to this function. Safe use of this function for example includes calls that request the next row and then
// serialize this result into a byte slice or send it as a gRPC message (which also serializes the result).
func NextBuffered(ctx context.Context, poolId, connId, rowsId int64) (*structpb.ListValue, error) {
return nextWithBufferOption(ctx, poolId, connId, rowsId /*resetBuffer=*/, false)
}

func nextWithBufferOption(ctx context.Context, poolId, connId, rowsId int64, resetBuffer bool) (*structpb.ListValue, error) {
values, _, err := next(ctx, poolId, connId, rowsId /*marshalResult=*/, false, resetBuffer)
if err != nil {
return nil, err
}
Expand All @@ -90,7 +103,7 @@ func Next(ctx context.Context, poolId, connId, rowsId int64) (*structpb.ListValu
// The row is returned as a protobuf ListValue if marshalResult==false.
// The row is returned as a byte slice if marshalResult==true.
// TODO: Add generics to the function and add input arguments for encoding instead of hardcoding it.
func next(ctx context.Context, poolId, connId, rowsId int64, marshalResult bool) (*structpb.ListValue, []byte, error) {
func next(ctx context.Context, poolId, connId, rowsId int64, marshalResult, resetBuffer bool) (*structpb.ListValue, []byte, error) {
rows, err := findRows(poolId, connId, rowsId)
if err != nil {
return nil, nil, err
Expand All @@ -99,6 +112,9 @@ func next(ctx context.Context, poolId, connId, rowsId int64, marshalResult bool)
if err != nil {
return nil, nil, err
}
if resetBuffer {
rows.buffer = nil
}
if !marshalResult || values == nil {
return values, nil, nil
}
Expand Down
Loading
Loading