Skip to content

Commit 26b1bb1

Browse files
committed
Add test for an optional struct inside an optional struct
1 parent e449916 commit 26b1bb1

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
@@ -437,12 +437,17 @@ func TestNamedQueryContext(t *testing.T) {
437437
"FIRST" text NULL,
438438
last_name text NULL,
439439
"EMAIL" text NULL
440+
);
441+
CREATE TABLE persondetails (
442+
email text NULL,
443+
notes text NULL
440444
);`,
441445
drop: `
442446
drop table person;
443447
drop table jsperson;
444448
drop table place;
445449
drop table placeperson;
450+
drop table persondetails;
446451
`,
447452
}
448453

@@ -648,8 +653,8 @@ func TestNamedQueryContext(t *testing.T) {
648653

649654
type Owner struct {
650655
Email *string `db:"email"`
651-
FirstName string `db:"first_name"`
652-
LastName string `db:"last_name"`
656+
FirstName string `db:"first_name"`
657+
LastName string `db:"last_name"`
653658
}
654659

655660
// Test optional nested structs with left join
@@ -680,11 +685,11 @@ func TestNamedQueryContext(t *testing.T) {
680685
pp3 := &PlaceOwner{}
681686
rows, err = db.NamedQueryContext(ctx, `
682687
SELECT
688+
place.id AS "place.id",
689+
place.name AS "place.name",
683690
placeperson.first_name "owner.first_name",
684691
placeperson.last_name "owner.last_name",
685-
placeperson.email "owner.email",
686-
place.id AS "place.id",
687-
place.name AS "place.name"
692+
placeperson.email "owner.email"
688693
FROM place
689694
LEFT JOIN placeperson ON false -- null left join
690695
WHERE
@@ -698,7 +703,7 @@ func TestNamedQueryContext(t *testing.T) {
698703
t.Error(err)
699704
}
700705
if pp3.Owner != nil {
701-
t.Error("Expected `Owner`, to be nil")
706+
t.Error("Expected `Owner` to be nil")
702707
}
703708
if pp3.Place.Name.String != "the-house" {
704709
t.Error("Expected place name of `the-house`, got " + pp3.Place.Name.String)
@@ -710,41 +715,160 @@ func TestNamedQueryContext(t *testing.T) {
710715

711716
rows.Close()
712717

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

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

0 commit comments

Comments
 (0)