Repository: surrealdb/surrealdb.go
Pull request #205 (2025-04-10 22:35:51)

docs-197-add-warning-for-unsupported-embedded-modes-in-readme
This PR updates the README.md to add a warning note under the ### Using SurrealKV and Memory section, clarifying that the Go SDK (surrealdb.go) currently does not support memory:// or surrealkv:// connection schemes.

Although example code exists for these embedded modes, they are not yet functional, and the SDK will panic with an “embedded database not enabled” error. This is being tracked in [issue #197](https://github.com/surrealdb/surrealdb.go/issues/197).

The added note aims to prevent confusion for contributors or users trying to use embedded modes based on outdated or misleading README examples. The note also suggests using http:// or ws:// endpoints instead.

🔗 Related issue: [#197](https://github.com/surrealdb/surrealdb.go/issues/197)


Patch:
diff --git a/README.md b/README.md
index c915324..3f76840 100644
--- a/README.md
+++ b/README.md
@@ -157,7 +157,7 @@ func main() {
 ```
 
 ### Doing it your way
-All Data manipulation methods are handled by an undelying `send` function. This function is 
+All Data manipulation methods are handled by an undelying `send` function. This function is
 exposed via `db.Send` function if you want to create requests yourself but limited to a selected set of methods. Theses
 methods are:
 - select
@@ -180,7 +180,7 @@ err := db.Send(&res, "query", user.ID)
 if err != nil {
 	panic(err)
 }
-	
+
 ```
 
 ### Instructions for running the example
@@ -217,9 +217,15 @@ db, err := surrealdb.New("https://localhost:8000")
 ```
 
 ### Using SurrealKV and Memory
-SurrealKV and Memory also do not support live notifications at this time. This would be updated in the next 
+SurrealKV and Memory also do not support live notifications at this time. This would be updated in the next
 release.
 
+> ⚠️ **Note**
+> Although the examples below reference `surrealkv://` and `memory://`, **these modes are currently not supported in the Go SDK**.
+> Support for embedded databases (like SurrealKV and in-memory) is pending future development and is being tracked in [issue #197](https://github.com/surrealdb/surrealdb.go/issues/197).
+>
+> Until then, please use `http://` or `ws://` endpoints to connect to a running SurrealDB server instance.
+
 For Surreal KV
 ```go
 db, err := surrealdb.New("surrealkv://path/to/dbfile.kv")
@@ -232,10 +238,10 @@ db, err := surrealdb.New("memory://")
 ```
 
 ## Data Models
-This package facilitates communication between client and the backend service using the Concise 
-Binary Object Representation (CBOR) format. It streamlines data serialization and deserialization 
-while ensuring efficient and lightweight communication. The library also provides custom models 
-tailored to specific Data models recognised by SurrealDb, which cannot be covered by idiomatic go, enabling seamless interaction between 
+This package facilitates communication between client and the backend service using the Concise
+Binary Object Representation (CBOR) format. It streamlines data serialization and deserialization
+while ensuring efficient and lightweight communication. The library also provides custom models
+tailored to specific Data models recognised by SurrealDb, which cannot be covered by idiomatic go, enabling seamless interaction between
 the client and the backend.
 
 See the [documetation on data models](https://surrealdb.com/docs/surrealql/datamodel) on support data types
diff --git a/pkg/models/cbor.go b/pkg/models/cbor.go
index 1863feb..6e26721 100644
--- a/pkg/models/cbor.go
+++ b/pkg/models/cbor.go
@@ -123,7 +123,8 @@ func getCborEncoder() cbor.EncMode {
 func getCborDecoder() cbor.DecMode {
 	tags := registerCborTags()
 	dm, err := cbor.DecOptions{
-		TimeTagToAny: cbor.TimeTagToTime,
+		TimeTagToAny:   cbor.TimeTagToTime,
+		DefaultMapType: reflect.TypeOf(map[string]any(nil)),
 	}.DecModeWithTags(tags)
 	if err != nil {
 		panic(err)


Test patch:
diff --git a/pkg/models/cbor_test.go b/pkg/models/cbor_test.go
index dd8bf27..f1a5ab6 100644
--- a/pkg/models/cbor_test.go
+++ b/pkg/models/cbor_test.go
@@ -1,6 +1,7 @@
 package models
 
 import (
+	"encoding/json"
 	"fmt"
 	"testing"
 	"time"
@@ -209,3 +210,49 @@ func TestFormatDuration(t *testing.T) {
 	d := FormatDuration(33333333333000000)
 	assert.Equal(t, "1y2w6d19h15m33s333ms", d)
 }
+
+func TestMapDecodingIssue207(t *testing.T) {
+	em := getCborEncoder()
+	dm := getCborDecoder()
+
+	// Test case reproducing issue #207
+	// When decoding maps, they should be decoded as map[string]interface{} for JSON compatibility
+	type DeviceProperties struct {
+		Desired  map[string]any `json:"desired"`
+		Reported map[string]any `json:"reported"`
+	}
+
+	// Create test data with nested maps
+	original := DeviceProperties{
+		Desired: map[string]any{
+			"temperature": 25.5,
+			"humidity":    60,
+			"settings": map[string]any{
+				"mode":  "auto",
+				"level": 3,
+			},
+		},
+		Reported: map[string]any{
+			"temperature": 24.8,
+			"humidity":    58,
+			"status":      "active",
+		},
+	}
+
+	// Although you can obviously round-trip the original struct using cbor...
+
+	encoded, err := em.Marshal(original)
+	assert.NoError(t, err, "Should not error while encoding")
+
+	var decoded DeviceProperties
+	err = dm.Unmarshal(encoded, &decoded)
+	assert.NoError(t, err, "Should not error while decoding")
+
+	// The nested settings map had been decoded as map[inetrface{}]interface{} instead of map[string]interface{}
+	// This is a problem for JSON marshaling, as it expects map[string]interface{}.
+
+	// By doing the following, we ensure that the map[string]interface{} that have nested maps
+	// are properly handled and can be marshaled to JSON without issues.
+	_, err = json.Marshal(decoded)
+	assert.NoError(t, err, "Should be able to marshal decoded struct to JSON")
+}