@@ -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