From 9d200733b9c63b84da7153d832c07fc914ce0ffa Mon Sep 17 00:00:00 2001 From: Jack Christensen Date: Fri, 4 Sep 2015 11:04:51 -0500 Subject: [PATCH] Merge common JSON and JSONB --- conn.go | 4 +-- query.go | 4 +-- values_test.go | 66 +++++++++++++++++++++++--------------------------- 3 files changed, 32 insertions(+), 42 deletions(-) diff --git a/conn.go b/conn.go index 411d69fb..fdc7fe59 100644 --- a/conn.go +++ b/conn.go @@ -799,9 +799,7 @@ func (c *Conn) sendPreparedQuery(ps *PreparedStatement, arguments ...interface{} err = encodeTimestampArray(wbuf, arguments[i], TimestampTzOid) case OidOid: err = encodeOid(wbuf, arguments[i]) - case JsonOid: - err = encodeJson(wbuf, arguments[i]) - case JsonbOid: + case JsonOid, JsonbOid: err = encodeJson(wbuf, arguments[i]) default: return SerializationError(fmt.Sprintf("Cannot encode %T into oid %v - %T must implement Encoder or be converted to a string", arg, oid, arg)) diff --git a/query.go b/query.go index 59ffbb3b..821648c9 100644 --- a/query.go +++ b/query.go @@ -285,9 +285,7 @@ func (rows *Rows) Scan(dest ...interface{}) (err error) { } default: switch vr.Type().DataType { - case JsonOid: - decodeJson(vr, &d) - case JsonbOid: + case JsonOid, JsonbOid: decodeJson(vr, &d) default: rows.Fatal(fmt.Errorf("Scan cannot decode into %T", d)) diff --git a/values_test.go b/values_test.go index 7ea118f3..6530d928 100644 --- a/values_test.go +++ b/values_test.go @@ -65,51 +65,45 @@ func TestTimestampTzTranscode(t *testing.T) { } } -func TestJsonTranscode(t *testing.T) { +func TestJsonAndJsonbTranscode(t *testing.T) { t.Parallel() conn := mustConnect(t, *defaultConnConfig) defer closeConn(t, conn) - if _, ok := conn.PgTypes[pgx.JsonOid]; !ok { - return // No JSON type -- must be running against old PostgreSQL - } + for _, oid := range []pgx.Oid{pgx.JsonOid, pgx.JsonbOid} { + if _, ok := conn.PgTypes[oid]; !ok { + return // No JSON/JSONB type -- must be running against old PostgreSQL + } + typename := conn.PgTypes[oid].Name - m := map[string]string{ - "key": "value", - } - var outputJson map[string]string + // Test single level objects with map[string]string + inStringMap := map[string]string{"key": "value"} + var outStringMap map[string]string + err := conn.QueryRow("select $1::"+typename, inStringMap).Scan(&outStringMap) + if err != nil { + t.Errorf("%s: QueryRow Scan failed: %v", typename, err) + } - err := conn.QueryRow("select $1::json", m).Scan(&outputJson) - if err != nil { - t.Fatalf("QueryRow Scan failed: %v", err) - } - if m["key"] != outputJson["key"] { - t.Errorf("Did not transcode json successfully: %v is not %v", outputJson["key"], m["key"]) - } -} + if !reflect.DeepEqual(inStringMap, outStringMap) { + t.Errorf("%s: Did not transcode map[string]string successfully: %v is not %v", typename, inStringMap, outStringMap) + } -func TestJsonbTranscode(t *testing.T) { - t.Parallel() + // Test nested objects with map[string]interface{} + inNestedMap := map[string]interface{}{ + "name": "Uncanny", + "stats": map[string]interface{}{"hp": 107, "maxhp": 150}, + "inventory": []string{"phone", "key"}, + } + var outNestedMap map[string]interface{} + err = conn.QueryRow("select $1::"+typename, inNestedMap).Scan(&outNestedMap) + if err != nil { + t.Errorf("%s: QueryRow Scan failed: %v", typename, err) + } - conn := mustConnect(t, *defaultConnConfig) - defer closeConn(t, conn) - - if _, ok := conn.PgTypes[pgx.JsonbOid]; !ok { - return // No JSONB type -- must be running against old PostgreSQL - } - - m := map[string]string{ - "key": "value", - } - var outputJson map[string]string - - err := conn.QueryRow("select $1::jsonb", m).Scan(&outputJson) - if err != nil { - t.Fatalf("QueryRow Scan failed: %v", err) - } - if m["key"] != outputJson["key"] { - t.Errorf("Did not transcode jsonb successfully: %v is not %v", outputJson["key"], m["key"]) + if !reflect.DeepEqual(inStringMap, outStringMap) { + t.Errorf("%s: Did not transcode map[string]interface{} successfully: %v is not %v", typename, inStringMap, outStringMap) + } } }