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