diff --git a/engine.go b/engine.go index 4984d374..f5af6d9d 100644 --- a/engine.go +++ b/engine.go @@ -1091,7 +1091,25 @@ func (engine *Engine) idOfV(rv reflect.Value) (core.PK, error) { pk := make([]interface{}, len(table.PrimaryKeys)) for i, col := range table.PKColumns() { var err error - pkField := v.FieldByName(col.FieldName) + + fieldName := col.FieldName + for { + parts := strings.SplitN(fieldName, ".", 2) + if len(parts) == 1 { + break + } + + v = v.FieldByName(parts[0]) + if v.Kind() == reflect.Ptr { + v = v.Elem() + } + if v.Kind() != reflect.Struct { + return nil, ErrUnSupportedType + } + fieldName = parts[1] + } + fmt.Println(table.Name, fieldName, v) + pkField := v.FieldByName(fieldName) switch pkField.Kind() { case reflect.String: pk[i], err = engine.idTypeAssertion(col, pkField.String()) diff --git a/error.go b/error.go index 1694683c..5dc6b84e 100644 --- a/error.go +++ b/error.go @@ -13,21 +13,21 @@ var ( // ErrParamsType params error ErrParamsType = errors.New("Params type error") // ErrTableNotFound table not found error - ErrTableNotFound = errors.New("Not found table") + ErrTableNotFound = errors.New("Table not found") // ErrUnSupportedType unsupported error ErrUnSupportedType = errors.New("Unsupported type error") - // ErrNotExist record is not exist error - ErrNotExist = errors.New("Not exist error") + // ErrNotExist record does not exist error + ErrNotExist = errors.New("Record does not exist") // ErrCacheFailed cache failed error ErrCacheFailed = errors.New("Cache failed") // ErrNeedDeletedCond delete needs less one condition error - ErrNeedDeletedCond = errors.New("Delete need at least one condition") + ErrNeedDeletedCond = errors.New("Delete action needs at least one condition") // ErrNotImplemented not implemented ErrNotImplemented = errors.New("Not implemented") // ErrConditionType condition type unsupported - ErrConditionType = errors.New("Unsupported conditon type") - // ErrColumnIsNotExist columns is not exist - ErrFieldIsNotExist = errors.New("Field is not exist") + ErrConditionType = errors.New("Unsupported condition type") + // ErrFieldIsNotExist columns does not exist + ErrFieldIsNotExist = errors.New("Field does not exist") ) // ErrFieldIsNotValid is not valid diff --git a/session_find_test.go b/session_find_test.go index 6a04dc57..c215fd57 100644 --- a/session_find_test.go +++ b/session_find_test.go @@ -655,5 +655,77 @@ func TestFindMapStringId(t *testing.T) { cnt, err = testEngine.ID("1").Delete(new(FindMapDevice)) assert.NoError(t, err) assert.EqualValues(t, 1, cnt) - +} + +func TestFindExtends(t *testing.T) { + type FindExtendsB struct { + ID int64 + } + + type FindExtendsA struct { + FindExtendsB `xorm:"extends"` + } + + assert.NoError(t, prepareEngine()) + assertSync(t, new(FindExtendsA)) + + cnt, err := testEngine.Insert(&FindExtendsA{ + FindExtendsB: FindExtendsB{}, + }) + assert.NoError(t, err) + assert.EqualValues(t, 1, cnt) + + cnt, err = testEngine.Insert(&FindExtendsA{ + FindExtendsB: FindExtendsB{}, + }) + assert.NoError(t, err) + assert.EqualValues(t, 1, cnt) + + var results []FindExtendsA + err = testEngine.Find(&results) + assert.NoError(t, err) + assert.EqualValues(t, 2, len(results)) +} + +func TestFindExtends3(t *testing.T) { + type FindExtendsCC struct { + ID int64 + Name string + } + + type FindExtendsBB struct { + FindExtendsCC `xorm:"extends"` + } + + type FindExtendsAA struct { + FindExtendsBB `xorm:"extends"` + } + + assert.NoError(t, prepareEngine()) + assertSync(t, new(FindExtendsAA)) + + cnt, err := testEngine.Insert(&FindExtendsAA{ + FindExtendsBB: FindExtendsBB{ + FindExtendsCC: FindExtendsCC{ + Name: "cc1", + }, + }, + }) + assert.NoError(t, err) + assert.EqualValues(t, 1, cnt) + + cnt, err = testEngine.Insert(&FindExtendsAA{ + FindExtendsBB: FindExtendsBB{ + FindExtendsCC: FindExtendsCC{ + Name: "cc2", + }, + }, + }) + assert.NoError(t, err) + assert.EqualValues(t, 1, cnt) + + var results []FindExtendsAA + err = testEngine.Find(&results) + assert.NoError(t, err) + assert.EqualValues(t, 2, len(results)) } diff --git a/session_insert_test.go b/session_insert_test.go index c87ae3a9..50943032 100644 --- a/session_insert_test.go +++ b/session_insert_test.go @@ -741,3 +741,42 @@ func TestInsertMulti4(t *testing.T) { assert.NoError(t, err) assert.EqualValues(t, len(users), cnt) } + +func TestAnonymousStruct(t *testing.T) { + type PlainObject struct { + ID uint64 `json:"id,string" xorm:"'ID' pk autoincr"` + Desc string `json:"desc" xorm:"'DESC' notnull"` + } + + type PlainFoo struct { + PlainObject `xorm:"extends"` // primary key defined in extends struct + + Width uint32 `json:"width" xorm:"'WIDTH' notnull"` + Height uint32 `json:"height" xorm:"'HEIGHT' notnull"` + + Ext struct { + F1 uint32 `json:"f1,omitempty"` + F2 uint32 `json:"f2,omitempty"` + } `json:"ext" xorm:"'EXT' json notnull"` + } + + assert.NoError(t, prepareEngine()) + assertSync(t, new(PlainFoo)) + + _, err := testEngine.Insert(&PlainFoo{ + PlainObject: PlainObject{ + Desc: "test", + }, + Width: 10, + Height: 20, + + Ext: struct { + F1 uint32 `json:"f1,omitempty"` + F2 uint32 `json:"f2,omitempty"` + }{ + F1: 11, + F2: 12, + }, + }) + assert.NoError(t, err) +}