CDC PB JSON

This commit is contained in:
Philip O'Toole
2025-09-09 18:05:49 -04:00
parent 65929b552b
commit 9caa1496bd
2 changed files with 49 additions and 0 deletions

View File

@@ -4,6 +4,8 @@ import (
"encoding/json"
"github.com/rqlite/rqlite/v8/command/proto"
"google.golang.org/protobuf/encoding/protojson"
"google.golang.org/protobuf/reflect/protoregistry"
)
// CDCMessagesEnvelope is the envelope for CDC messages as transported over HTTP.
@@ -72,3 +74,22 @@ func MarshalToEnvelopeJSON(serviceID, nodeID string, ts bool, evs []*proto.CDCIn
func UnmarshalFromEnvelopeJSON(data []byte, env *CDCMessagesEnvelope) error {
return json.Unmarshal(data, env)
}
var pj = protojson.MarshalOptions{
// Control JSON shape:
// - UseProtoNames: snake_case field names from .proto instead of lowerCamel JSON names
// - EmitUnpopulated: include fields with zero values
// - UseEnumNumbers: render enums as integers (false => strings)
UseProtoNames: true,
EmitUnpopulated: false,
UseEnumNumbers: false,
// Resolve google.protobuf.Any to type URLs if you use Any:
Resolver: protoregistry.GlobalTypes,
}
func WriteJSON(m *proto.CDCIndexedEventGroup) ([]byte, error) {
// Marshal directly to []byte; write it immediately.
// Avoid string conversions (which copy) and avoid extra buffers.
return pj.Marshal(m)
}

28
cdc/json/marshal_test.go Normal file
View File

@@ -0,0 +1,28 @@
package json
import (
"fmt"
"testing"
"github.com/rqlite/rqlite/v8/command/proto"
)
func Test_Single(t *testing.T) {
e := &proto.CDCIndexedEventGroup{
Index: 1,
CommitTimestamp: 123456789,
Events: []*proto.CDCEvent{
{
Op: proto.CDCEvent_INSERT,
Table: "users",
NewRowId: 42,
},
},
}
b, err := WriteJSON(e)
if err != nil {
t.Fatalf("failed to marshal: %s", err)
}
fmt.Println(string(b))
}