diff --git a/document_meta.go b/document_meta.go index 3010c2a6..ccfc6e3e 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,17 @@ 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 + } + if tag := sf.Tag.Get("db"); strings.HasSuffix(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..d084834f 100644 --- a/document_test.go +++ b/document_test.go @@ -234,6 +234,34 @@ 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"` + 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}, + "embedded": {3}, + } + ) + + assert.Equal(t, index, doc.Index()) +} + func TestDocument_EmbeddedNameConfict(t *testing.T) { type Embedded struct { Name string