package orm_test import ( "reflect" "github.com/go-pg/pg/orm" "github.com/go-pg/pg/types" . "github.com/onsi/ginkgo" . "github.com/onsi/gomega" ) type A struct { Id int } func (A) Method() int { return 10 } type B struct { A } var _ = Describe("embedded Model", func() { var strct reflect.Value var table *orm.Table BeforeEach(func() { strct = reflect.ValueOf(B{A: A{Id: 1}}) table = orm.GetTable(strct.Type()) }) It("has fields", func() { Expect(table.Fields).To(HaveLen(1)) Expect(table.FieldsMap).To(HaveLen(1)) id, ok := table.FieldsMap["id"] Expect(ok).To(BeTrue()) Expect(id.GoName).To(Equal("Id")) Expect(id.SQLName).To(Equal("id")) Expect(string(id.Column)).To(Equal(`"id"`)) Expect(id.HasFlag(orm.PrimaryKeyFlag)).To(BeTrue()) Expect(string(id.AppendValue(nil, strct, 1))).To(Equal("1")) Expect(table.PKs).To(HaveLen(1)) Expect(table.PKs[0]).To(Equal(id)) }) It("has methods", func() { Expect(table.Methods).To(HaveLen(1)) m, ok := table.Methods["Method"] Expect(ok).To(BeTrue()) Expect(m.Index).To(Equal(0)) Expect(string(m.AppendValue(nil, strct, 1))).To(Equal("10")) }) }) type C struct { Name int `sql:",pk"` Id int UUID int } var _ = Describe("primary key annotation", func() { var table *orm.Table BeforeEach(func() { strct := reflect.ValueOf(C{}) table = orm.GetTable(strct.Type()) }) It("has precedence over auto-detection", func() { Expect(table.PKs).To(HaveLen(1)) Expect(table.PKs[0].GoName).To(Equal("Name")) }) }) type D struct { UUID int } var _ = Describe("uuid field", func() { var table *orm.Table BeforeEach(func() { strct := reflect.ValueOf(D{}) table = orm.GetTable(strct.Type()) }) It("is detected as primary key", func() { Expect(table.PKs).To(HaveLen(1)) Expect(table.PKs[0].GoName).To(Equal("UUID")) }) }) type E struct { Id int StructField struct { Foo string Bar string } } var _ = Describe("struct field", func() { var table *orm.Table BeforeEach(func() { strct := reflect.ValueOf(E{}) table = orm.GetTable(strct.Type()) }) It("is present in the list", func() { Expect(table.Fields).To(HaveLen(2)) _, ok := table.FieldsMap["struct_field"] Expect(ok).To(BeTrue()) }) }) type f struct { Id int G *g } type g struct { Id int FId int F *f } var _ = Describe("unexported types", func() { It("work with belongs to relation", func() { strct := reflect.ValueOf(f{}) table := orm.GetTable(strct.Type()) rel, ok := table.Relations["G"] Expect(ok).To(BeTrue()) Expect(rel.Type).To(Equal(orm.BelongsToRelation)) }) It("work with has one relation", func() { strct := reflect.ValueOf(g{}) table := orm.GetTable(strct.Type()) rel, ok := table.Relations["F"] Expect(ok).To(BeTrue()) Expect(rel.Type).To(Equal(orm.HasOneRelation)) }) }) type H struct { I *I } type I struct { H *H } var _ = Describe("model with circular reference", func() { It("works", func() { table := orm.GetTable(reflect.TypeOf(H{})) Expect(table).NotTo(BeNil()) table = orm.GetTable(reflect.TypeOf(I{})) Expect(table).NotTo(BeNil()) }) }) type J struct { JId int64 `sql:",pk"` } type K struct { KId int64 `sql:",pk"` MyId int64 My *J } var _ = Describe("ModelId fk", func() { It("is autodetected", func() { table := orm.GetTable(reflect.TypeOf(K{})) Expect(table).NotTo(BeNil()) rel := table.Relations["My"] Expect(rel).NotTo(BeNil()) }) }) type L struct { Id int64 } var _ = Describe("ModelId fk and anonymous model", func() { It("is autodetected", func() { var res struct { Items []L } table := orm.GetTable(reflect.TypeOf(res)) Expect(table).NotTo(BeNil()) field := table.FieldsMap["items"] Expect(field).NotTo(BeNil()) rel := table.Relations["Items"] Expect(rel).To(BeNil()) }) }) type M struct { Id int64 Name string } type N struct { M Id string } var _ = Describe("embedding", func() { It("handles overwriting", func() { table := orm.GetTable(reflect.TypeOf(N{})) Expect(table.Fields).To(HaveLen(2)) Expect(table.FieldsMap).To(HaveLen(2)) Expect(table.PKs).To(HaveLen(1)) Expect(table.DataFields).To(HaveLen(1)) field := table.FieldsMap["id"] Expect(field.SQLType).To(Equal("text")) }) }) var _ = Describe("anonymous struct", func() { It("has an alias", func() { var model struct { tableName struct{} `sql:"some_name"` ID uint64 Data string } table := orm.GetTable(reflect.TypeOf(model)) Expect(table.FullName).To(Equal(types.Q("some_name"))) Expect(table.FullNameForSelects).To(Equal(types.Q("some_name"))) Expect(table.Alias).To(Equal(types.Q("some_name"))) }) }) type O struct { M Id struct{} `sql:"-"` } var _ = Describe("embedding with ignored field", func() { It("ignores field", func() { table := orm.GetTable(reflect.TypeOf(O{})) Expect(table.Fields).To(HaveLen(1)) Expect(table.FieldsMap).To(HaveLen(2)) Expect(table.PKs).To(HaveLen(0)) Expect(table.DataFields).To(HaveLen(1)) }) })