From 5d1923f8ae6b307546bb53fbf28c3b15014ea216 Mon Sep 17 00:00:00 2001 From: Andrea Peruffo Date: Wed, 15 Jan 2025 18:52:44 +0000 Subject: [PATCH 1/2] Implement specific accessors for all the Struct data types --- debezium.go | 90 ++++++++++++++++++++++++++++++-------- it/debezium_test.go | 87 ++++++++++++++++++++---------------- it/testdata/test4.wasm | Bin 5167 -> 0 bytes testdata-project/test4.go | 12 ----- 4 files changed, 121 insertions(+), 68 deletions(-) delete mode 100644 it/testdata/test4.wasm delete mode 100644 testdata-project/test4.go diff --git a/debezium.go b/debezium.go index 4355714..cd913d6 100644 --- a/debezium.go +++ b/debezium.go @@ -1,7 +1,6 @@ package debezium import ( - "strconv" "unsafe" "github.com/debezium/debezium-smt-go-pdk/internal" @@ -24,9 +23,47 @@ func GetString(proxyPtr uint32) string { return result } -// materialize the Numeric content referenced -func GetInt(proxyPtr uint32) uint32 { - return envGetInt(proxyPtr) +// materialize the Boolean content referenced +func GetBool(proxyPtr uint32) bool { + return envGetBool(proxyPtr) > 0 +} + +// materialize the Bytes content referenced +func GetBytes(proxyPtr uint32) []byte { + var resultPtr = envGetBytes(proxyPtr) + var result = internal.ReadCString(resultPtr) + internal.Free(unsafe.Pointer(uintptr(resultPtr))) + return []byte(result) +} + +// materialize the Float32 content referenced +func GetFloat32(proxyPtr uint32) float32 { + return envGetFloat32(proxyPtr) +} + +// materialize the Float64 content referenced +func GetFloat64(proxyPtr uint32) float64 { + return envGetFloat64(proxyPtr) +} + +// materialize the Int16 content referenced +func GetInt16(proxyPtr uint32) int16 { + return int16(envGetInt16(proxyPtr)) +} + +// materialize the Int32 content referenced +func GetInt32(proxyPtr uint32) int32 { + return envGetInt32(proxyPtr) +} + +// materialize the Int64 content referenced +func GetInt64(proxyPtr uint32) int64 { + return envGetInt64(proxyPtr) +} + +// materialize the Int8 content referenced +func GetInt8(proxyPtr uint32) int8 { + return int8(envGetInt8(proxyPtr)) } // check whenever the referenced content is Null @@ -60,15 +97,6 @@ func SetString(value string) uint32 { return envSetString(uint32(uintptr(valuePtr))) } -// set a Numeric content for the Debezium Host -func SetInt(value uint32) uint32 { - bs := []byte(strconv.Itoa(int(value))) - var valuePtr = internal.Malloc(uintptr(len(bs) + 1)) - internal.WriteCString(uintptr(valuePtr), string(bs)) - - return envSetInt(uint32(uintptr(valuePtr))) -} - //go:wasm-module env //export get_string func envGetString(proxyPtr uint32) uint32 @@ -85,10 +113,6 @@ func envIsNull(valuePtr uint32) uint32 //export set_string func envSetString(valuePtr uint32) uint32 -//go:wasm-module env -//export set_int -func envSetInt(valuePtr uint32) uint32 - //go:wasm-module env //export set_bool func envSetBool(valuePtr uint32) uint32 @@ -98,5 +122,33 @@ func envSetBool(valuePtr uint32) uint32 func envGet(proxyPtr, fieldNamePtr uint32) uint32 //go:wasm-module env -//export get_int -func envGetInt(proxyPtr uint32) uint32 +//export get_bool +func envGetBool(proxyPtr uint32) uint32 + +//go:wasm-module env +//export get_bytes +func envGetBytes(proxyPtr uint32) uint32 + +//go:wasm-module env +//export get_float32 +func envGetFloat32(proxyPtr uint32) float32 + +//go:wasm-module env +//export get_float64 +func envGetFloat64(proxyPtr uint32) float64 + +//go:wasm-module env +//export get_int16 +func envGetInt16(proxyPtr uint32) uint32 + +//go:wasm-module env +//export get_int32 +func envGetInt32(proxyPtr uint32) int32 + +//go:wasm-module env +//export get_int64 +func envGetInt64(proxyPtr uint32) int64 + +//go:wasm-module env +//export get_int8 +func envGetInt8(proxyPtr uint32) uint32 diff --git a/it/debezium_test.go b/it/debezium_test.go index 2928b18..6f8de38 100644 --- a/it/debezium_test.go +++ b/it/debezium_test.go @@ -6,7 +6,6 @@ import ( "context" _ "embed" "log" - "strconv" "github.com/stretchr/testify/assert" @@ -15,7 +14,6 @@ import ( var get_string_ptr uint32 var set_string_ptr uint32 -var set_int uint32 // wazero module builder func wazeroStub(ctx context.Context) wazero.Runtime { @@ -32,37 +30,66 @@ func wazeroStub(ctx context.Context) wazero.Runtime { WithFunc(func(v uint32) uint32 { return 2 }). - Export("get_int"). + Export("get_bool"). NewFunctionBuilder(). - WithFunc(func(v1, v2 uint32) uint32 { + WithFunc(func(v uint32) uint32 { return 3 }). - Export("get"). + Export("get_bytes"). NewFunctionBuilder(). WithFunc(func(v uint32) uint32 { return 4 }). - Export("set_bool"). + Export("get_float32"). NewFunctionBuilder(). - WithFunc(func(v uint32) uint32 { - set_int = v + WithFunc(func(v uint32) uint64 { return 5 }). - Export("set_int"). + Export("get_float64"). NewFunctionBuilder(). WithFunc(func(v uint32) uint32 { - set_string_ptr = v return 6 }). + Export("get_int16"). + NewFunctionBuilder(). + WithFunc(func(v uint32) uint32 { + return 7 + }). + Export("get_int32"). + NewFunctionBuilder(). + WithFunc(func(v1 uint32) uint32 { + return 8 + }). + Export("get_int64"). + NewFunctionBuilder(). + WithFunc(func(v uint32) int64 { + return 9 + }). + Export("get_int8"). + NewFunctionBuilder(). + WithFunc(func(v1, v2 uint32) uint32 { + return 10 + }). + Export("get"). + NewFunctionBuilder(). + WithFunc(func(v uint32) uint32 { + return 11 + }). + Export("set_bool"). + NewFunctionBuilder(). + WithFunc(func(v uint32) uint32 { + set_string_ptr = v + return 12 + }). Export("set_string"). NewFunctionBuilder(). WithFunc(func() uint32 { - return 7 + return 13 }). Export("set_null"). NewFunctionBuilder(). WithFunc(func(v uint32) uint32 { - return 8 + return 14 }). Export("is_null"). Instantiate(ctx) @@ -82,10 +109,16 @@ func TestGuestNull(t *testing.T) { var r = wazeroStub(ctx) defer r.Close(ctx) - mod, _ := r.Instantiate(ctx, test1Wasm) - res, _ := mod.ExportedFunction("process").Call(ctx, 0) + mod, err := r.Instantiate(ctx, test1Wasm) + if err != nil { + log.Panicln(err) + } + res, err := mod.ExportedFunction("process").Call(ctx, 0) + if err != nil { + log.Panicln(err) + } - assert.Equal(t, res[0], uint64(7)) + assert.Equal(t, uint64(13), res[0]) } //go:embed testdata/test2.wasm @@ -99,7 +132,7 @@ func TestGuestString(t *testing.T) { mod, _ := r.Instantiate(ctx, test2Wasm) res, _ := mod.ExportedFunction("process").Call(ctx, 0) - assert.Equal(t, res[0], uint64(6)) + assert.Equal(t, uint64(12), res[0]) buf, _ := mod.Memory().Read(set_string_ptr, 3) assert.Equal(t, "foo", string(buf)) @@ -122,28 +155,8 @@ func TestHostString(t *testing.T) { res, _ := mod.ExportedFunction("process").Call(ctx, namePtr) - assert.Equal(t, res[0], uint64(6)) + assert.Equal(t, uint64(12), res[0]) buf, _ := mod.Memory().Read(set_string_ptr, 3) assert.Equal(t, "baz", string(buf)) } - -//go:embed testdata/test4.wasm -var test4Wasm []byte - -func TestGuestNumbers(t *testing.T) { - var ctx = context.Background() - var r = wazeroStub(ctx) - defer r.Close(ctx) - - mod, _ := r.Instantiate(ctx, test4Wasm) - - res, _ := mod.ExportedFunction("process").Call(ctx, 123) - - assert.Equal(t, res[0], uint64(5)) - - buf, _ := mod.Memory().Read(set_int, 3) - myInt, _ := strconv.Atoi(string(buf)) - - assert.Equal(t, myInt, 123) -} diff --git a/it/testdata/test4.wasm b/it/testdata/test4.wasm deleted file mode 100644 index c07a2771d66211eb2e8eab696e14ac122ca0577c..0000000000000000000000000000000000000000 GIT binary patch literal 0 HcmV?d00001 literal 5167 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 Date: Wed, 15 Jan 2025 18:53:44 +0000 Subject: [PATCH 2/2] update doc --- Readme.md | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/Readme.md b/Readme.md index 3f56a94..ee022c6 100644 --- a/Readme.md +++ b/Readme.md @@ -49,7 +49,7 @@ For efficiency reasons the full content of the record is not transferred to the debezium.GetString(debezium.Get(proxyPtr, "value.op")) ``` -where `debezium.Get` is used to access the required field with a familiar dot(`.`) syntax, and `debezium.GetString` (or `debezium.IsNull`, `debezium.GetInt`) materialize the value. +where `debezium.Get` is used to access the required field with a familiar dot(`.`) syntax, and `debezium.GetString` (or `debezium.IsNull`, `debezium.GetInt32`, etc.) materialize the value. Similarly, returning a value to Debezium is performed using the PDK functionalities: @@ -57,4 +57,4 @@ Similarly, returning a value to Debezium is performed using the PDK functionalit return debezium.SetString("foobar") ``` -the value returned by the `Set` function (or `SetNull`, `SetBool`, `SetInt` ...) should be returned as the result of the `process` function. +the value returned by the `Set` function (or `SetNull`, `SetBool`, `SetString` ...) should be returned as the result of the `process` function.