Skip to content

Commit 7b63394

Browse files
committed
Add test for an optional struct inside an optional struct
1 parent 54352ec commit 7b63394

File tree

1 file changed

+144
-20
lines changed

1 file changed

+144
-20
lines changed

sqlx_context_test.go

Lines changed: 144 additions & 20 deletions
Original file line numberDiff line numberDiff line change
@@ -436,12 +436,17 @@ func TestNamedQueryContext(t *testing.T) {
436436
"FIRST" text NULL,
437437
last_name text NULL,
438438
"EMAIL" text NULL
439+
);
440+
CREATE TABLE persondetails (
441+
email text NULL,
442+
notes text NULL
439443
);`,
440444
drop: `
441445
drop table person;
442446
drop table jsperson;
443447
drop table place;
444448
drop table placeperson;
449+
drop table persondetails;
445450
`,
446451
}
447452

@@ -647,8 +652,8 @@ func TestNamedQueryContext(t *testing.T) {
647652

648653
type Owner struct {
649654
Email *string `db:"email"`
650-
FirstName string `db:"first_name"`
651-
LastName string `db:"last_name"`
655+
FirstName string `db:"first_name"`
656+
LastName string `db:"last_name"`
652657
}
653658

654659
// Test optional nested structs with left join
@@ -679,11 +684,11 @@ func TestNamedQueryContext(t *testing.T) {
679684
pp3 := &PlaceOwner{}
680685
rows, err = db.NamedQueryContext(ctx, `
681686
SELECT
687+
place.id AS "place.id",
688+
place.name AS "place.name",
682689
placeperson.first_name "owner.first_name",
683690
placeperson.last_name "owner.last_name",
684-
placeperson.email "owner.email",
685-
place.id AS "place.id",
686-
place.name AS "place.name"
691+
placeperson.email "owner.email"
687692
FROM place
688693
LEFT JOIN placeperson ON false -- null left join
689694
WHERE
@@ -697,7 +702,7 @@ func TestNamedQueryContext(t *testing.T) {
697702
t.Error(err)
698703
}
699704
if pp3.Owner != nil {
700-
t.Error("Expected `Owner`, to be nil")
705+
t.Error("Expected `Owner` to be nil")
701706
}
702707
if pp3.Place.Name.String != "the-house" {
703708
t.Error("Expected place name of `the-house`, got " + pp3.Place.Name.String)
@@ -709,41 +714,160 @@ func TestNamedQueryContext(t *testing.T) {
709714

710715
rows.Close()
711716

712-
pp3 = &PlaceOwner{}
717+
pp4 := &PlaceOwner{}
713718
rows, err = db.NamedQueryContext(ctx, `
714719
SELECT
720+
place.id AS "place.id",
721+
place.name AS "place.name",
715722
placeperson.first_name "owner.first_name",
716723
placeperson.last_name "owner.last_name",
717-
placeperson.email "owner.email",
724+
placeperson.email "owner.email"
725+
FROM place
726+
LEFT JOIN placeperson ON placeperson.place_id = place.id
727+
WHERE
728+
place.id=:place.id`, pp)
729+
if err != nil {
730+
log.Fatal(err)
731+
}
732+
for rows.Next() {
733+
err = rows.StructScan(pp4)
734+
if err != nil {
735+
t.Error(err)
736+
}
737+
if pp4.Owner == nil {
738+
t.Error("Expected `Owner` to not be nil")
739+
}
740+
if pp4.Owner.FirstName != "ben" {
741+
t.Error("Expected first name of `ben`, got " + pp4.Owner.FirstName)
742+
}
743+
if pp4.Owner.LastName != "doe" {
744+
t.Error("Expected first name of `doe`, got " + pp4.Owner.LastName)
745+
}
746+
if pp4.Place.Name.String != "the-house" {
747+
t.Error("Expected place name of `the-house`, got " + pp4.Place.Name.String)
748+
}
749+
if pp4.Place.ID != pp.Place.ID {
750+
t.Errorf("Expected place name of %v, got %v", pp.Place.ID, pp4.Place.ID)
751+
}
752+
}
753+
754+
type Details struct {
755+
Email string `db:"email"`
756+
Notes string `db:"notes"`
757+
}
758+
759+
type OwnerDetails struct {
760+
Email *string `db:"email"`
761+
FirstName string `db:"first_name"`
762+
LastName string `db:"last_name"`
763+
Details *Details `db:"details"`
764+
}
765+
766+
type PlaceOwnerDetails struct {
767+
Place Place `db:"place"`
768+
Owner *OwnerDetails `db:"owner"`
769+
}
770+
771+
pp5 := &PlaceOwnerDetails{}
772+
rows, err = db.NamedQueryContext(ctx, `
773+
SELECT
718774
place.id AS "place.id",
719-
place.name AS "place.name"
775+
place.name AS "place.name",
776+
placeperson.first_name "owner.first_name",
777+
placeperson.last_name "owner.last_name",
778+
placeperson.email "owner.email",
779+
persondetails.email "owner.details.email",
780+
persondetails.notes "owner.details.notes"
720781
FROM place
721-
left JOIN placeperson ON placeperson.place_id = place.id
782+
LEFT JOIN placeperson ON placeperson.place_id = place.id
783+
LEFT JOIN persondetails ON false
722784
WHERE
723785
place.id=:place.id`, pp)
724786
if err != nil {
725787
log.Fatal(err)
726788
}
727789
for rows.Next() {
728-
err = rows.StructScan(pp3)
790+
err = rows.StructScan(pp5)
729791
if err != nil {
730792
t.Error(err)
731793
}
732-
if pp3.Owner == nil {
794+
if pp5.Owner == nil {
733795
t.Error("Expected `Owner`, to not be nil")
734796
}
797+
if pp5.Owner.FirstName != "ben" {
798+
t.Error("Expected first name of `ben`, got " + pp5.Owner.FirstName)
799+
}
800+
if pp5.Owner.LastName != "doe" {
801+
t.Error("Expected first name of `doe`, got " + pp5.Owner.LastName)
802+
}
803+
if pp5.Place.Name.String != "the-house" {
804+
t.Error("Expected place name of `the-house`, got " + pp5.Place.Name.String)
805+
}
806+
if pp5.Place.ID != pp.Place.ID {
807+
t.Errorf("Expected place name of %v, got %v", pp.Place.ID, pp5.Place.ID)
808+
}
809+
if pp5.Owner.Details != nil {
810+
t.Error("Expected `Details` to be nil")
811+
}
812+
}
813+
814+
details := Details{
815+
Email: pp.Email.String,
816+
Notes: "this is a test person",
817+
}
735818

736-
if pp3.Owner.FirstName != "ben" {
737-
t.Error("Expected first name of `ben`, got " + pp3.Owner.FirstName)
819+
q6 := `INSERT INTO persondetails (email, notes) VALUES (:email, :notes)`
820+
_, err = db.NamedExecContext(ctx, q6, details)
821+
if err != nil {
822+
log.Fatal(err)
823+
}
824+
825+
pp6 := &PlaceOwnerDetails{}
826+
rows, err = db.NamedQueryContext(ctx, `
827+
SELECT
828+
place.id AS "place.id",
829+
place.name AS "place.name",
830+
placeperson.first_name "owner.first_name",
831+
placeperson.last_name "owner.last_name",
832+
placeperson.email "owner.email",
833+
persondetails.email "owner.details.email",
834+
persondetails.notes "owner.details.notes"
835+
FROM place
836+
LEFT JOIN placeperson ON placeperson.place_id = place.id
837+
LEFT JOIN persondetails ON persondetails.email = placeperson.email
838+
WHERE
839+
place.id=:place.id`, pp)
840+
if err != nil {
841+
log.Fatal(err)
842+
}
843+
for rows.Next() {
844+
err = rows.StructScan(pp6)
845+
if err != nil {
846+
t.Error(err)
738847
}
739-
if pp3.Owner.LastName != "doe" {
740-
t.Error("Expected first name of `doe`, got " + pp3.Owner.LastName)
848+
if pp6.Owner == nil {
849+
t.Error("Expected `Owner` to not be nil")
741850
}
742-
if pp3.Place.Name.String != "the-house" {
743-
t.Error("Expected place name of `the-house`, got " + pp3.Place.Name.String)
851+
if pp6.Owner.FirstName != "ben" {
852+
t.Error("Expected first name of `ben`, got " + pp6.Owner.FirstName)
744853
}
745-
if pp3.Place.ID != pp.Place.ID {
746-
t.Errorf("Expected place name of %v, got %v", pp.Place.ID, pp3.Place.ID)
854+
if pp6.Owner.LastName != "doe" {
855+
t.Error("Expected first name of `doe`, got " + pp6.Owner.LastName)
856+
}
857+
if pp6.Place.Name.String != "the-house" {
858+
t.Error("Expected place name of `the-house`, got " + pp6.Place.Name.String)
859+
}
860+
if pp6.Place.ID != pp.Place.ID {
861+
t.Errorf("Expected place name of %v, got %v", pp.Place.ID, pp6.Place.ID)
862+
}
863+
if pp6.Owner.Details == nil {
864+
t.Error("Expected `Details` to not be nil")
865+
}
866+
if pp6.Owner.Details.Email != details.Email {
867+
t.Errorf("Expected details email of %v, got %v", details.Email, pp6.Owner.Details.Email)
868+
}
869+
if pp6.Owner.Details.Notes != details.Notes {
870+
t.Errorf("Expected details notes of %v, got %v", details.Notes, pp6.Owner.Details.Notes)
747871
}
748872
}
749873
})

0 commit comments

Comments
 (0)