From d928a97150a254c0bfb8290a5bace6e16b5b8901 Mon Sep 17 00:00:00 2001 From: Vladislav Oleshko Date: Mon, 4 Jul 2022 14:17:14 +0300 Subject: [PATCH 1/3] Allow named structs to be embedded --- document_meta.go | 17 ++++++++++++++++- document_test.go | 26 ++++++++++++++++++++++++++ 2 files changed, 42 insertions(+), 1 deletion(-) diff --git a/document_meta.go b/document_meta.go index 3010c2a6..a2f39693 100644 --- a/document_meta.go +++ b/document_meta.go @@ -238,7 +238,7 @@ func getDocumentMeta(rt reflect.Type, skipAssoc bool) DocumentMeta { typ = typ.Elem() } - if typ.Kind() == reflect.Struct && sf.Anonymous { + if typ.Kind() == reflect.Struct && isEmbedded(sf) { embedded := getDocumentMeta(typ, skipAssoc) embeddedName := "" if tagged { @@ -357,6 +357,21 @@ func fieldName(sf reflect.StructField) (string, bool) { return snaker.CamelToSnake(sf.Name), false } +func isEmbedded(sf reflect.StructField) bool { + // anonymous structs are always embedded + if sf.Anonymous { + return true + } + // search for embedded tag + tags := strings.Split(sf.Tag.Get("db"), ",") + for _, tag := range tags { + if tag == "embedded" { + return true + } + } + return false +} + func searchPrimary(rt reflect.Type) ([]string, [][]int) { if result, cached := primariesCache.Load(rt); cached { p := result.(primaryData) diff --git a/document_test.go b/document_test.go index 631b366d..51aa87b6 100644 --- a/document_test.go +++ b/document_test.go @@ -234,6 +234,32 @@ func TestDocument_IndexEmbedded(t *testing.T) { assert.Equal(t, index, doc.Index()) } +func TestDocument_IndexFieldEmbedded(t *testing.T) { + type FirstEmbedded struct { + A int + B int + } + type SecondEmbedded struct { + D float32 + } + var ( + record = struct { + First FirstEmbedded `db:"first_,embedded"` + C string + Second SecondEmbedded `db:",embedded"` + }{} + doc = NewDocument(&record) + index = map[string][]int{ + "first_a": {0, 0}, + "first_b": {0, 1}, + "c": {1}, + "d": {2, 0}, + } + ) + + assert.Equal(t, index, doc.Index()) +} + func TestDocument_EmbeddedNameConfict(t *testing.T) { type Embedded struct { Name string From bd1294da214fd2567266697a08ce0ffd8ce41744 Mon Sep 17 00:00:00 2001 From: Vladislav Oleshko Date: Mon, 4 Jul 2022 14:27:00 +0300 Subject: [PATCH 2/3] Fix name issue --- document_meta.go | 4 ++-- document_test.go | 10 ++++++---- 2 files changed, 8 insertions(+), 6 deletions(-) diff --git a/document_meta.go b/document_meta.go index a2f39693..2f2ffb43 100644 --- a/document_meta.go +++ b/document_meta.go @@ -364,8 +364,8 @@ func isEmbedded(sf reflect.StructField) bool { } // search for embedded tag tags := strings.Split(sf.Tag.Get("db"), ",") - for _, tag := range tags { - if tag == "embedded" { + for i, tag := range tags { + if tag == "embedded" && i > 0 { return true } } diff --git a/document_test.go b/document_test.go index 51aa87b6..d084834f 100644 --- a/document_test.go +++ b/document_test.go @@ -247,13 +247,15 @@ func TestDocument_IndexFieldEmbedded(t *testing.T) { First FirstEmbedded `db:"first_,embedded"` C string Second SecondEmbedded `db:",embedded"` + E int `db:"embedded"` // this field is not embedded, but only called so }{} doc = NewDocument(&record) index = map[string][]int{ - "first_a": {0, 0}, - "first_b": {0, 1}, - "c": {1}, - "d": {2, 0}, + "first_a": {0, 0}, + "first_b": {0, 1}, + "c": {1}, + "d": {2, 0}, + "embedded": {3}, } ) From 2112d2857c33935fe9a3fc0f09be7f7bbaa566ef Mon Sep 17 00:00:00 2001 From: Vladislav Oleshko Date: Mon, 4 Jul 2022 17:16:04 +0300 Subject: [PATCH 3/3] Replace loop with HasSuffix --- document_meta.go | 8 ++------ 1 file changed, 2 insertions(+), 6 deletions(-) diff --git a/document_meta.go b/document_meta.go index 2f2ffb43..ccfc6e3e 100644 --- a/document_meta.go +++ b/document_meta.go @@ -362,12 +362,8 @@ func isEmbedded(sf reflect.StructField) bool { if sf.Anonymous { return true } - // search for embedded tag - tags := strings.Split(sf.Tag.Get("db"), ",") - for i, tag := range tags { - if tag == "embedded" && i > 0 { - return true - } + if tag := sf.Tag.Get("db"); strings.HasSuffix(tag, ",embedded") { + return true } return false }