From 2bc0e18b9ed9393d6c215c280f51993fb407d7e3 Mon Sep 17 00:00:00 2001 From: Eli Ribble Date: Sat, 14 Feb 2026 05:40:27 +0000 Subject: [PATCH] Actually finish uploaded files --- db/dbinfo/fileupload.pool.bob.go | 108 ++-- db/factory/bobfactory_context.bob.go | 12 +- db/factory/bobfactory_main.bob.go | 16 +- db/factory/comms.phone.bob.go | 185 +++++- db/factory/fileupload.pool.bob.go | 422 +++++++----- db/migrations/00062_csv_pool_phone_fix.sql | 5 + db/models/comms.phone.bob.go | 515 +++++++++++++++ db/models/fileupload.pool.bob.go | 710 ++++++++++++++++----- platform/csv/pool.go | 40 +- 9 files changed, 1618 insertions(+), 395 deletions(-) create mode 100644 db/migrations/00062_csv_pool_phone_fix.sql diff --git a/db/dbinfo/fileupload.pool.bob.go b/db/dbinfo/fileupload.pool.bob.go index 4b7a6635..aac9e82a 100644 --- a/db/dbinfo/fileupload.pool.bob.go +++ b/db/dbinfo/fileupload.pool.bob.go @@ -168,15 +168,6 @@ var FileuploadPools = Table[ Generated: false, AutoIncr: false, }, - PropertyOwnerPhone: column{ - Name: "property_owner_phone", - DBType: "phone", - Default: "NULL", - Comment: "", - Nullable: true, - Generated: false, - AutoIncr: false, - }, ResidentOwned: column{ Name: "resident_owned", DBType: "boolean", @@ -186,15 +177,6 @@ var FileuploadPools = Table[ Generated: false, AutoIncr: false, }, - ResidentPhone: column{ - Name: "resident_phone", - DBType: "phone", - Default: "NULL", - Comment: "", - Nullable: true, - Generated: false, - AutoIncr: false, - }, Version: column{ Name: "version", DBType: "integer", @@ -204,6 +186,24 @@ var FileuploadPools = Table[ Generated: false, AutoIncr: false, }, + PropertyOwnerPhoneE164: column{ + Name: "property_owner_phone_e164", + DBType: "text", + Default: "NULL", + Comment: "", + Nullable: true, + Generated: false, + AutoIncr: false, + }, + ResidentPhoneE164: column{ + Name: "resident_phone_e164", + DBType: "text", + Default: "NULL", + Comment: "", + Nullable: true, + Generated: false, + AutoIncr: false, + }, }, Indexes: fileuploadPoolIndexes{ PoolPkey: index{ @@ -262,38 +262,56 @@ var FileuploadPools = Table[ ForeignTable: "organization", ForeignColumns: []string{"id"}, }, + FileuploadPoolPoolPropertyOwnerPhoneE164Fkey: foreignKey{ + constraint: constraint{ + Name: "fileupload.pool.pool_property_owner_phone_e164_fkey", + Columns: []string{"property_owner_phone_e164"}, + Comment: "", + }, + ForeignTable: "comms.phone", + ForeignColumns: []string{"e164"}, + }, + FileuploadPoolPoolResidentPhoneE164Fkey: foreignKey{ + constraint: constraint{ + Name: "fileupload.pool.pool_resident_phone_e164_fkey", + Columns: []string{"resident_phone_e164"}, + Comment: "", + }, + ForeignTable: "comms.phone", + ForeignColumns: []string{"e164"}, + }, }, Comment: "", } type fileuploadPoolColumns struct { - AddressCity column - AddressPostalCode column - AddressStreet column - Committed column - Condition column - Created column - CreatorID column - CSVFile column - Deleted column - Geom column - H3cell column - ID column - IsInDistrict column - IsNew column - Notes column - OrganizationID column - PropertyOwnerName column - PropertyOwnerPhone column - ResidentOwned column - ResidentPhone column - Version column + AddressCity column + AddressPostalCode column + AddressStreet column + Committed column + Condition column + Created column + CreatorID column + CSVFile column + Deleted column + Geom column + H3cell column + ID column + IsInDistrict column + IsNew column + Notes column + OrganizationID column + PropertyOwnerName column + ResidentOwned column + Version column + PropertyOwnerPhoneE164 column + ResidentPhoneE164 column } func (c fileuploadPoolColumns) AsSlice() []column { return []column{ - c.AddressCity, c.AddressPostalCode, c.AddressStreet, c.Committed, c.Condition, c.Created, c.CreatorID, c.CSVFile, c.Deleted, c.Geom, c.H3cell, c.ID, c.IsInDistrict, c.IsNew, c.Notes, c.OrganizationID, c.PropertyOwnerName, c.PropertyOwnerPhone, c.ResidentOwned, c.ResidentPhone, c.Version, + c.AddressCity, c.AddressPostalCode, c.AddressStreet, c.Committed, c.Condition, c.Created, c.CreatorID, c.CSVFile, c.Deleted, c.Geom, c.H3cell, c.ID, c.IsInDistrict, c.IsNew, c.Notes, c.OrganizationID, c.PropertyOwnerName, c.ResidentOwned, c.Version, c.PropertyOwnerPhoneE164, c.ResidentPhoneE164, } } @@ -308,14 +326,16 @@ func (i fileuploadPoolIndexes) AsSlice() []index { } type fileuploadPoolForeignKeys struct { - FileuploadPoolPoolCreatorIDFkey foreignKey - FileuploadPoolPoolCSVFileFkey foreignKey - FileuploadPoolPoolOrganizationIDFkey foreignKey + FileuploadPoolPoolCreatorIDFkey foreignKey + FileuploadPoolPoolCSVFileFkey foreignKey + FileuploadPoolPoolOrganizationIDFkey foreignKey + FileuploadPoolPoolPropertyOwnerPhoneE164Fkey foreignKey + FileuploadPoolPoolResidentPhoneE164Fkey foreignKey } func (f fileuploadPoolForeignKeys) AsSlice() []foreignKey { return []foreignKey{ - f.FileuploadPoolPoolCreatorIDFkey, f.FileuploadPoolPoolCSVFileFkey, f.FileuploadPoolPoolOrganizationIDFkey, + f.FileuploadPoolPoolCreatorIDFkey, f.FileuploadPoolPoolCSVFileFkey, f.FileuploadPoolPoolOrganizationIDFkey, f.FileuploadPoolPoolPropertyOwnerPhoneE164Fkey, f.FileuploadPoolPoolResidentPhoneE164Fkey, } } diff --git a/db/factory/bobfactory_context.bob.go b/db/factory/bobfactory_context.bob.go index 8bae75d7..a3a9efae 100644 --- a/db/factory/bobfactory_context.bob.go +++ b/db/factory/bobfactory_context.bob.go @@ -40,6 +40,8 @@ var ( commsPhoneRelDestinationTextLogsCtx = newContextual[bool]("comms.phone.comms.text_log.comms.text_log.text_log_destination_fkey") commsPhoneRelSourceTextLogsCtx = newContextual[bool]("comms.phone.comms.text_log.comms.text_log.text_log_source_fkey") commsPhoneRelOrganizationsCtx = newContextual[bool]("comms.phone.organization.district_subscription_phone.district_subscription_phone_organization_id_fkeydistrict_subscription_phone.district_subscription_phone_phone_e164_fkey") + commsPhoneRelPropertyOwnerPhoneE164PoolsCtx = newContextual[bool]("comms.phone.fileupload.pool.fileupload.pool.pool_property_owner_phone_e164_fkey") + commsPhoneRelResidentPhoneE164PoolsCtx = newContextual[bool]("comms.phone.fileupload.pool.fileupload.pool.pool_resident_phone_e164_fkey") commsPhoneRelPhoneE164NotifyPhoneNuisancesCtx = newContextual[bool]("comms.phone.publicreport.notify_phone_nuisance.publicreport.notify_phone_nuisance.notify_phone_nuisance_phone_e164_fkey") commsPhoneRelPhoneE164NotifyPhonePoolsCtx = newContextual[bool]("comms.phone.publicreport.notify_phone_pool.publicreport.notify_phone_pool.notify_phone_pool_phone_e164_fkey") commsPhoneRelPhoneE164SubscribePhonesCtx = newContextual[bool]("comms.phone.publicreport.subscribe_phone.publicreport.subscribe_phone.subscribe_phone_phone_e164_fkey") @@ -197,10 +199,12 @@ var ( fileuploadFileRelOrganizationCtx = newContextual[bool]("fileupload.file.organization.fileupload.file.file_organization_id_fkey") // Relationship Contexts for fileupload.pool - fileuploadPoolWithParentsCascadingCtx = newContextual[bool]("fileuploadPoolWithParentsCascading") - fileuploadPoolRelCreatorUserCtx = newContextual[bool]("fileupload.pool.user_.fileupload.pool.pool_creator_id_fkey") - fileuploadPoolRelCSVFileCSVCtx = newContextual[bool]("fileupload.csv.fileupload.pool.fileupload.pool.pool_csv_file_fkey") - fileuploadPoolRelOrganizationCtx = newContextual[bool]("fileupload.pool.organization.fileupload.pool.pool_organization_id_fkey") + fileuploadPoolWithParentsCascadingCtx = newContextual[bool]("fileuploadPoolWithParentsCascading") + fileuploadPoolRelCreatorUserCtx = newContextual[bool]("fileupload.pool.user_.fileupload.pool.pool_creator_id_fkey") + fileuploadPoolRelCSVFileCSVCtx = newContextual[bool]("fileupload.csv.fileupload.pool.fileupload.pool.pool_csv_file_fkey") + fileuploadPoolRelOrganizationCtx = newContextual[bool]("fileupload.pool.organization.fileupload.pool.pool_organization_id_fkey") + fileuploadPoolRelPropertyOwnerPhoneE164PhoneCtx = newContextual[bool]("comms.phone.fileupload.pool.fileupload.pool.pool_property_owner_phone_e164_fkey") + fileuploadPoolRelResidentPhoneE164PhoneCtx = newContextual[bool]("comms.phone.fileupload.pool.fileupload.pool.pool_resident_phone_e164_fkey") // Relationship Contexts for geography_columns geographyColumnWithParentsCascadingCtx = newContextual[bool]("geographyColumnWithParentsCascading") diff --git a/db/factory/bobfactory_main.bob.go b/db/factory/bobfactory_main.bob.go index 2238ff2e..de6e0aea 100644 --- a/db/factory/bobfactory_main.bob.go +++ b/db/factory/bobfactory_main.bob.go @@ -335,6 +335,12 @@ func (f *Factory) FromExistingCommsPhone(m *models.CommsPhone) *CommsPhoneTempla if len(m.R.Organizations) > 0 { CommsPhoneMods.AddExistingOrganizations(m.R.Organizations...).Apply(ctx, o) } + if len(m.R.PropertyOwnerPhoneE164Pools) > 0 { + CommsPhoneMods.AddExistingPropertyOwnerPhoneE164Pools(m.R.PropertyOwnerPhoneE164Pools...).Apply(ctx, o) + } + if len(m.R.ResidentPhoneE164Pools) > 0 { + CommsPhoneMods.AddExistingResidentPhoneE164Pools(m.R.ResidentPhoneE164Pools...).Apply(ctx, o) + } if len(m.R.PhoneE164NotifyPhoneNuisances) > 0 { CommsPhoneMods.AddExistingPhoneE164NotifyPhoneNuisances(m.R.PhoneE164NotifyPhoneNuisances...).Apply(ctx, o) } @@ -2427,10 +2433,10 @@ func (f *Factory) FromExistingFileuploadPool(m *models.FileuploadPool) *Fileuplo o.Notes = func() string { return m.Notes } o.OrganizationID = func() int32 { return m.OrganizationID } o.PropertyOwnerName = func() string { return m.PropertyOwnerName } - o.PropertyOwnerPhone = func() null.Val[string] { return m.PropertyOwnerPhone } o.ResidentOwned = func() null.Val[bool] { return m.ResidentOwned } - o.ResidentPhone = func() null.Val[string] { return m.ResidentPhone } o.Version = func() int32 { return m.Version } + o.PropertyOwnerPhoneE164 = func() null.Val[string] { return m.PropertyOwnerPhoneE164 } + o.ResidentPhoneE164 = func() null.Val[string] { return m.ResidentPhoneE164 } ctx := context.Background() if m.R.CreatorUser != nil { @@ -2442,6 +2448,12 @@ func (f *Factory) FromExistingFileuploadPool(m *models.FileuploadPool) *Fileuplo if m.R.Organization != nil { FileuploadPoolMods.WithExistingOrganization(m.R.Organization).Apply(ctx, o) } + if m.R.PropertyOwnerPhoneE164Phone != nil { + FileuploadPoolMods.WithExistingPropertyOwnerPhoneE164Phone(m.R.PropertyOwnerPhoneE164Phone).Apply(ctx, o) + } + if m.R.ResidentPhoneE164Phone != nil { + FileuploadPoolMods.WithExistingResidentPhoneE164Phone(m.R.ResidentPhoneE164Phone).Apply(ctx, o) + } return o } diff --git a/db/factory/comms.phone.bob.go b/db/factory/comms.phone.bob.go index 23c43c7d..b2d5ff6e 100644 --- a/db/factory/comms.phone.bob.go +++ b/db/factory/comms.phone.bob.go @@ -10,6 +10,7 @@ import ( "github.com/Gleipnir-Technology/bob" enums "github.com/Gleipnir-Technology/nidus-sync/db/enums" models "github.com/Gleipnir-Technology/nidus-sync/db/models" + "github.com/aarondl/opt/null" "github.com/aarondl/opt/omit" "github.com/jaswdr/faker/v2" ) @@ -50,6 +51,8 @@ type commsPhoneR struct { DestinationTextLogs []*commsPhoneRDestinationTextLogsR SourceTextLogs []*commsPhoneRSourceTextLogsR Organizations []*commsPhoneROrganizationsR + PropertyOwnerPhoneE164Pools []*commsPhoneRPropertyOwnerPhoneE164PoolsR + ResidentPhoneE164Pools []*commsPhoneRResidentPhoneE164PoolsR PhoneE164NotifyPhoneNuisances []*commsPhoneRPhoneE164NotifyPhoneNuisancesR PhoneE164NotifyPhonePools []*commsPhoneRPhoneE164NotifyPhonePoolsR PhoneE164SubscribePhones []*commsPhoneRPhoneE164SubscribePhonesR @@ -71,6 +74,14 @@ type commsPhoneROrganizationsR struct { number int o *OrganizationTemplate } +type commsPhoneRPropertyOwnerPhoneE164PoolsR struct { + number int + o *FileuploadPoolTemplate +} +type commsPhoneRResidentPhoneE164PoolsR struct { + number int + o *FileuploadPoolTemplate +} type commsPhoneRPhoneE164NotifyPhoneNuisancesR struct { number int o *PublicreportNotifyPhoneNuisanceTemplate @@ -145,6 +156,32 @@ func (t CommsPhoneTemplate) setModelRels(o *models.CommsPhone) { o.R.Organizations = rel } + if t.r.PropertyOwnerPhoneE164Pools != nil { + rel := models.FileuploadPoolSlice{} + for _, r := range t.r.PropertyOwnerPhoneE164Pools { + related := r.o.BuildMany(r.number) + for _, rel := range related { + rel.PropertyOwnerPhoneE164 = null.From(o.E164) // h2 + rel.R.PropertyOwnerPhoneE164Phone = o + } + rel = append(rel, related...) + } + o.R.PropertyOwnerPhoneE164Pools = rel + } + + if t.r.ResidentPhoneE164Pools != nil { + rel := models.FileuploadPoolSlice{} + for _, r := range t.r.ResidentPhoneE164Pools { + related := r.o.BuildMany(r.number) + for _, rel := range related { + rel.ResidentPhoneE164 = null.From(o.E164) // h2 + rel.R.ResidentPhoneE164Phone = o + } + rel = append(rel, related...) + } + o.R.ResidentPhoneE164Pools = rel + } + if t.r.PhoneE164NotifyPhoneNuisances != nil { rel := models.PublicreportNotifyPhoneNuisanceSlice{} for _, r := range t.r.PhoneE164NotifyPhoneNuisances { @@ -353,6 +390,46 @@ func (o *CommsPhoneTemplate) insertOptRels(ctx context.Context, exec bob.Executo } } + isPropertyOwnerPhoneE164PoolsDone, _ := commsPhoneRelPropertyOwnerPhoneE164PoolsCtx.Value(ctx) + if !isPropertyOwnerPhoneE164PoolsDone && o.r.PropertyOwnerPhoneE164Pools != nil { + ctx = commsPhoneRelPropertyOwnerPhoneE164PoolsCtx.WithValue(ctx, true) + for _, r := range o.r.PropertyOwnerPhoneE164Pools { + if r.o.alreadyPersisted { + m.R.PropertyOwnerPhoneE164Pools = append(m.R.PropertyOwnerPhoneE164Pools, r.o.Build()) + } else { + rel4, err := r.o.CreateMany(ctx, exec, r.number) + if err != nil { + return err + } + + err = m.AttachPropertyOwnerPhoneE164Pools(ctx, exec, rel4...) + if err != nil { + return err + } + } + } + } + + isResidentPhoneE164PoolsDone, _ := commsPhoneRelResidentPhoneE164PoolsCtx.Value(ctx) + if !isResidentPhoneE164PoolsDone && o.r.ResidentPhoneE164Pools != nil { + ctx = commsPhoneRelResidentPhoneE164PoolsCtx.WithValue(ctx, true) + for _, r := range o.r.ResidentPhoneE164Pools { + if r.o.alreadyPersisted { + m.R.ResidentPhoneE164Pools = append(m.R.ResidentPhoneE164Pools, r.o.Build()) + } else { + rel5, err := r.o.CreateMany(ctx, exec, r.number) + if err != nil { + return err + } + + err = m.AttachResidentPhoneE164Pools(ctx, exec, rel5...) + if err != nil { + return err + } + } + } + } + isPhoneE164NotifyPhoneNuisancesDone, _ := commsPhoneRelPhoneE164NotifyPhoneNuisancesCtx.Value(ctx) if !isPhoneE164NotifyPhoneNuisancesDone && o.r.PhoneE164NotifyPhoneNuisances != nil { ctx = commsPhoneRelPhoneE164NotifyPhoneNuisancesCtx.WithValue(ctx, true) @@ -360,12 +437,12 @@ func (o *CommsPhoneTemplate) insertOptRels(ctx context.Context, exec bob.Executo if r.o.alreadyPersisted { m.R.PhoneE164NotifyPhoneNuisances = append(m.R.PhoneE164NotifyPhoneNuisances, r.o.Build()) } else { - rel4, err := r.o.CreateMany(ctx, exec, r.number) + rel6, err := r.o.CreateMany(ctx, exec, r.number) if err != nil { return err } - err = m.AttachPhoneE164NotifyPhoneNuisances(ctx, exec, rel4...) + err = m.AttachPhoneE164NotifyPhoneNuisances(ctx, exec, rel6...) if err != nil { return err } @@ -380,12 +457,12 @@ func (o *CommsPhoneTemplate) insertOptRels(ctx context.Context, exec bob.Executo if r.o.alreadyPersisted { m.R.PhoneE164NotifyPhonePools = append(m.R.PhoneE164NotifyPhonePools, r.o.Build()) } else { - rel5, err := r.o.CreateMany(ctx, exec, r.number) + rel7, err := r.o.CreateMany(ctx, exec, r.number) if err != nil { return err } - err = m.AttachPhoneE164NotifyPhonePools(ctx, exec, rel5...) + err = m.AttachPhoneE164NotifyPhonePools(ctx, exec, rel7...) if err != nil { return err } @@ -400,12 +477,12 @@ func (o *CommsPhoneTemplate) insertOptRels(ctx context.Context, exec bob.Executo if r.o.alreadyPersisted { m.R.PhoneE164SubscribePhones = append(m.R.PhoneE164SubscribePhones, r.o.Build()) } else { - rel6, err := r.o.CreateMany(ctx, exec, r.number) + rel8, err := r.o.CreateMany(ctx, exec, r.number) if err != nil { return err } - err = m.AttachPhoneE164SubscribePhones(ctx, exec, rel6...) + err = m.AttachPhoneE164SubscribePhones(ctx, exec, rel8...) if err != nil { return err } @@ -805,6 +882,102 @@ func (m commsPhoneMods) WithoutOrganizations() CommsPhoneMod { }) } +func (m commsPhoneMods) WithPropertyOwnerPhoneE164Pools(number int, related *FileuploadPoolTemplate) CommsPhoneMod { + return CommsPhoneModFunc(func(ctx context.Context, o *CommsPhoneTemplate) { + o.r.PropertyOwnerPhoneE164Pools = []*commsPhoneRPropertyOwnerPhoneE164PoolsR{{ + number: number, + o: related, + }} + }) +} + +func (m commsPhoneMods) WithNewPropertyOwnerPhoneE164Pools(number int, mods ...FileuploadPoolMod) CommsPhoneMod { + return CommsPhoneModFunc(func(ctx context.Context, o *CommsPhoneTemplate) { + related := o.f.NewFileuploadPoolWithContext(ctx, mods...) + m.WithPropertyOwnerPhoneE164Pools(number, related).Apply(ctx, o) + }) +} + +func (m commsPhoneMods) AddPropertyOwnerPhoneE164Pools(number int, related *FileuploadPoolTemplate) CommsPhoneMod { + return CommsPhoneModFunc(func(ctx context.Context, o *CommsPhoneTemplate) { + o.r.PropertyOwnerPhoneE164Pools = append(o.r.PropertyOwnerPhoneE164Pools, &commsPhoneRPropertyOwnerPhoneE164PoolsR{ + number: number, + o: related, + }) + }) +} + +func (m commsPhoneMods) AddNewPropertyOwnerPhoneE164Pools(number int, mods ...FileuploadPoolMod) CommsPhoneMod { + return CommsPhoneModFunc(func(ctx context.Context, o *CommsPhoneTemplate) { + related := o.f.NewFileuploadPoolWithContext(ctx, mods...) + m.AddPropertyOwnerPhoneE164Pools(number, related).Apply(ctx, o) + }) +} + +func (m commsPhoneMods) AddExistingPropertyOwnerPhoneE164Pools(existingModels ...*models.FileuploadPool) CommsPhoneMod { + return CommsPhoneModFunc(func(ctx context.Context, o *CommsPhoneTemplate) { + for _, em := range existingModels { + o.r.PropertyOwnerPhoneE164Pools = append(o.r.PropertyOwnerPhoneE164Pools, &commsPhoneRPropertyOwnerPhoneE164PoolsR{ + o: o.f.FromExistingFileuploadPool(em), + }) + } + }) +} + +func (m commsPhoneMods) WithoutPropertyOwnerPhoneE164Pools() CommsPhoneMod { + return CommsPhoneModFunc(func(ctx context.Context, o *CommsPhoneTemplate) { + o.r.PropertyOwnerPhoneE164Pools = nil + }) +} + +func (m commsPhoneMods) WithResidentPhoneE164Pools(number int, related *FileuploadPoolTemplate) CommsPhoneMod { + return CommsPhoneModFunc(func(ctx context.Context, o *CommsPhoneTemplate) { + o.r.ResidentPhoneE164Pools = []*commsPhoneRResidentPhoneE164PoolsR{{ + number: number, + o: related, + }} + }) +} + +func (m commsPhoneMods) WithNewResidentPhoneE164Pools(number int, mods ...FileuploadPoolMod) CommsPhoneMod { + return CommsPhoneModFunc(func(ctx context.Context, o *CommsPhoneTemplate) { + related := o.f.NewFileuploadPoolWithContext(ctx, mods...) + m.WithResidentPhoneE164Pools(number, related).Apply(ctx, o) + }) +} + +func (m commsPhoneMods) AddResidentPhoneE164Pools(number int, related *FileuploadPoolTemplate) CommsPhoneMod { + return CommsPhoneModFunc(func(ctx context.Context, o *CommsPhoneTemplate) { + o.r.ResidentPhoneE164Pools = append(o.r.ResidentPhoneE164Pools, &commsPhoneRResidentPhoneE164PoolsR{ + number: number, + o: related, + }) + }) +} + +func (m commsPhoneMods) AddNewResidentPhoneE164Pools(number int, mods ...FileuploadPoolMod) CommsPhoneMod { + return CommsPhoneModFunc(func(ctx context.Context, o *CommsPhoneTemplate) { + related := o.f.NewFileuploadPoolWithContext(ctx, mods...) + m.AddResidentPhoneE164Pools(number, related).Apply(ctx, o) + }) +} + +func (m commsPhoneMods) AddExistingResidentPhoneE164Pools(existingModels ...*models.FileuploadPool) CommsPhoneMod { + return CommsPhoneModFunc(func(ctx context.Context, o *CommsPhoneTemplate) { + for _, em := range existingModels { + o.r.ResidentPhoneE164Pools = append(o.r.ResidentPhoneE164Pools, &commsPhoneRResidentPhoneE164PoolsR{ + o: o.f.FromExistingFileuploadPool(em), + }) + } + }) +} + +func (m commsPhoneMods) WithoutResidentPhoneE164Pools() CommsPhoneMod { + return CommsPhoneModFunc(func(ctx context.Context, o *CommsPhoneTemplate) { + o.r.ResidentPhoneE164Pools = nil + }) +} + func (m commsPhoneMods) WithPhoneE164NotifyPhoneNuisances(number int, related *PublicreportNotifyPhoneNuisanceTemplate) CommsPhoneMod { return CommsPhoneModFunc(func(ctx context.Context, o *CommsPhoneTemplate) { o.r.PhoneE164NotifyPhoneNuisances = []*commsPhoneRPhoneE164NotifyPhoneNuisancesR{{ diff --git a/db/factory/fileupload.pool.bob.go b/db/factory/fileupload.pool.bob.go index 058ef448..1621c9f9 100644 --- a/db/factory/fileupload.pool.bob.go +++ b/db/factory/fileupload.pool.bob.go @@ -38,27 +38,27 @@ func (mods FileuploadPoolModSlice) Apply(ctx context.Context, n *FileuploadPoolT // FileuploadPoolTemplate is an object representing the database table. // all columns are optional and should be set by mods type FileuploadPoolTemplate struct { - AddressCity func() string - AddressPostalCode func() string - AddressStreet func() string - Committed func() bool - Condition func() enums.FileuploadPoolconditiontype - Created func() time.Time - CreatorID func() int32 - CSVFile func() int32 - Deleted func() null.Val[time.Time] - Geom func() null.Val[string] - H3cell func() null.Val[string] - ID func() int32 - IsInDistrict func() bool - IsNew func() bool - Notes func() string - OrganizationID func() int32 - PropertyOwnerName func() string - PropertyOwnerPhone func() null.Val[string] - ResidentOwned func() null.Val[bool] - ResidentPhone func() null.Val[string] - Version func() int32 + AddressCity func() string + AddressPostalCode func() string + AddressStreet func() string + Committed func() bool + Condition func() enums.FileuploadPoolconditiontype + Created func() time.Time + CreatorID func() int32 + CSVFile func() int32 + Deleted func() null.Val[time.Time] + Geom func() null.Val[string] + H3cell func() null.Val[string] + ID func() int32 + IsInDistrict func() bool + IsNew func() bool + Notes func() string + OrganizationID func() int32 + PropertyOwnerName func() string + ResidentOwned func() null.Val[bool] + Version func() int32 + PropertyOwnerPhoneE164 func() null.Val[string] + ResidentPhoneE164 func() null.Val[string] r fileuploadPoolR f *Factory @@ -67,9 +67,11 @@ type FileuploadPoolTemplate struct { } type fileuploadPoolR struct { - CreatorUser *fileuploadPoolRCreatorUserR - CSVFileCSV *fileuploadPoolRCSVFileCSVR - Organization *fileuploadPoolROrganizationR + CreatorUser *fileuploadPoolRCreatorUserR + CSVFileCSV *fileuploadPoolRCSVFileCSVR + Organization *fileuploadPoolROrganizationR + PropertyOwnerPhoneE164Phone *fileuploadPoolRPropertyOwnerPhoneE164PhoneR + ResidentPhoneE164Phone *fileuploadPoolRResidentPhoneE164PhoneR } type fileuploadPoolRCreatorUserR struct { @@ -81,6 +83,12 @@ type fileuploadPoolRCSVFileCSVR struct { type fileuploadPoolROrganizationR struct { o *OrganizationTemplate } +type fileuploadPoolRPropertyOwnerPhoneE164PhoneR struct { + o *CommsPhoneTemplate +} +type fileuploadPoolRResidentPhoneE164PhoneR struct { + o *CommsPhoneTemplate +} // Apply mods to the FileuploadPoolTemplate func (o *FileuploadPoolTemplate) Apply(ctx context.Context, mods ...FileuploadPoolMod) { @@ -112,6 +120,20 @@ func (t FileuploadPoolTemplate) setModelRels(o *models.FileuploadPool) { o.OrganizationID = rel.ID // h2 o.R.Organization = rel } + + if t.r.PropertyOwnerPhoneE164Phone != nil { + rel := t.r.PropertyOwnerPhoneE164Phone.o.Build() + rel.R.PropertyOwnerPhoneE164Pools = append(rel.R.PropertyOwnerPhoneE164Pools, o) + o.PropertyOwnerPhoneE164 = null.From(rel.E164) // h2 + o.R.PropertyOwnerPhoneE164Phone = rel + } + + if t.r.ResidentPhoneE164Phone != nil { + rel := t.r.ResidentPhoneE164Phone.o.Build() + rel.R.ResidentPhoneE164Pools = append(rel.R.ResidentPhoneE164Pools, o) + o.ResidentPhoneE164 = null.From(rel.E164) // h2 + o.R.ResidentPhoneE164Phone = rel + } } // BuildSetter returns an *models.FileuploadPoolSetter @@ -187,22 +209,22 @@ func (o FileuploadPoolTemplate) BuildSetter() *models.FileuploadPoolSetter { val := o.PropertyOwnerName() m.PropertyOwnerName = omit.From(val) } - if o.PropertyOwnerPhone != nil { - val := o.PropertyOwnerPhone() - m.PropertyOwnerPhone = omitnull.FromNull(val) - } if o.ResidentOwned != nil { val := o.ResidentOwned() m.ResidentOwned = omitnull.FromNull(val) } - if o.ResidentPhone != nil { - val := o.ResidentPhone() - m.ResidentPhone = omitnull.FromNull(val) - } if o.Version != nil { val := o.Version() m.Version = omit.From(val) } + if o.PropertyOwnerPhoneE164 != nil { + val := o.PropertyOwnerPhoneE164() + m.PropertyOwnerPhoneE164 = omitnull.FromNull(val) + } + if o.ResidentPhoneE164 != nil { + val := o.ResidentPhoneE164() + m.ResidentPhoneE164 = omitnull.FromNull(val) + } return m } @@ -276,18 +298,18 @@ func (o FileuploadPoolTemplate) Build() *models.FileuploadPool { if o.PropertyOwnerName != nil { m.PropertyOwnerName = o.PropertyOwnerName() } - if o.PropertyOwnerPhone != nil { - m.PropertyOwnerPhone = o.PropertyOwnerPhone() - } if o.ResidentOwned != nil { m.ResidentOwned = o.ResidentOwned() } - if o.ResidentPhone != nil { - m.ResidentPhone = o.ResidentPhone() - } if o.Version != nil { m.Version = o.Version() } + if o.PropertyOwnerPhoneE164 != nil { + m.PropertyOwnerPhoneE164 = o.PropertyOwnerPhoneE164() + } + if o.ResidentPhoneE164 != nil { + m.ResidentPhoneE164 = o.ResidentPhoneE164() + } o.setModelRels(m) @@ -372,6 +394,44 @@ func ensureCreatableFileuploadPool(m *models.FileuploadPoolSetter) { func (o *FileuploadPoolTemplate) insertOptRels(ctx context.Context, exec bob.Executor, m *models.FileuploadPool) error { var err error + isPropertyOwnerPhoneE164PhoneDone, _ := fileuploadPoolRelPropertyOwnerPhoneE164PhoneCtx.Value(ctx) + if !isPropertyOwnerPhoneE164PhoneDone && o.r.PropertyOwnerPhoneE164Phone != nil { + ctx = fileuploadPoolRelPropertyOwnerPhoneE164PhoneCtx.WithValue(ctx, true) + if o.r.PropertyOwnerPhoneE164Phone.o.alreadyPersisted { + m.R.PropertyOwnerPhoneE164Phone = o.r.PropertyOwnerPhoneE164Phone.o.Build() + } else { + var rel3 *models.CommsPhone + rel3, err = o.r.PropertyOwnerPhoneE164Phone.o.Create(ctx, exec) + if err != nil { + return err + } + err = m.AttachPropertyOwnerPhoneE164Phone(ctx, exec, rel3) + if err != nil { + return err + } + } + + } + + isResidentPhoneE164PhoneDone, _ := fileuploadPoolRelResidentPhoneE164PhoneCtx.Value(ctx) + if !isResidentPhoneE164PhoneDone && o.r.ResidentPhoneE164Phone != nil { + ctx = fileuploadPoolRelResidentPhoneE164PhoneCtx.WithValue(ctx, true) + if o.r.ResidentPhoneE164Phone.o.alreadyPersisted { + m.R.ResidentPhoneE164Phone = o.r.ResidentPhoneE164Phone.o.Build() + } else { + var rel4 *models.CommsPhone + rel4, err = o.r.ResidentPhoneE164Phone.o.Create(ctx, exec) + if err != nil { + return err + } + err = m.AttachResidentPhoneE164Phone(ctx, exec, rel4) + if err != nil { + return err + } + } + + } + return err } @@ -536,10 +596,10 @@ func (m fileuploadPoolMods) RandomizeAllColumns(f *faker.Faker) FileuploadPoolMo FileuploadPoolMods.RandomNotes(f), FileuploadPoolMods.RandomOrganizationID(f), FileuploadPoolMods.RandomPropertyOwnerName(f), - FileuploadPoolMods.RandomPropertyOwnerPhone(f), FileuploadPoolMods.RandomResidentOwned(f), - FileuploadPoolMods.RandomResidentPhone(f), FileuploadPoolMods.RandomVersion(f), + FileuploadPoolMods.RandomPropertyOwnerPhoneE164(f), + FileuploadPoolMods.RandomResidentPhoneE164(f), } } @@ -1136,59 +1196,6 @@ func (m fileuploadPoolMods) RandomPropertyOwnerName(f *faker.Faker) FileuploadPo }) } -// Set the model columns to this value -func (m fileuploadPoolMods) PropertyOwnerPhone(val null.Val[string]) FileuploadPoolMod { - return FileuploadPoolModFunc(func(_ context.Context, o *FileuploadPoolTemplate) { - o.PropertyOwnerPhone = func() null.Val[string] { return val } - }) -} - -// Set the Column from the function -func (m fileuploadPoolMods) PropertyOwnerPhoneFunc(f func() null.Val[string]) FileuploadPoolMod { - return FileuploadPoolModFunc(func(_ context.Context, o *FileuploadPoolTemplate) { - o.PropertyOwnerPhone = f - }) -} - -// Clear any values for the column -func (m fileuploadPoolMods) UnsetPropertyOwnerPhone() FileuploadPoolMod { - return FileuploadPoolModFunc(func(_ context.Context, o *FileuploadPoolTemplate) { - o.PropertyOwnerPhone = nil - }) -} - -// Generates a random value for the column using the given faker -// if faker is nil, a default faker is used -// The generated value is sometimes null -func (m fileuploadPoolMods) RandomPropertyOwnerPhone(f *faker.Faker) FileuploadPoolMod { - return FileuploadPoolModFunc(func(_ context.Context, o *FileuploadPoolTemplate) { - o.PropertyOwnerPhone = func() null.Val[string] { - if f == nil { - f = &defaultFaker - } - - val := random_string(f) - return null.From(val) - } - }) -} - -// Generates a random value for the column using the given faker -// if faker is nil, a default faker is used -// The generated value is never null -func (m fileuploadPoolMods) RandomPropertyOwnerPhoneNotNull(f *faker.Faker) FileuploadPoolMod { - return FileuploadPoolModFunc(func(_ context.Context, o *FileuploadPoolTemplate) { - o.PropertyOwnerPhone = func() null.Val[string] { - if f == nil { - f = &defaultFaker - } - - val := random_string(f) - return null.From(val) - } - }) -} - // Set the model columns to this value func (m fileuploadPoolMods) ResidentOwned(val null.Val[bool]) FileuploadPoolMod { return FileuploadPoolModFunc(func(_ context.Context, o *FileuploadPoolTemplate) { @@ -1242,59 +1249,6 @@ func (m fileuploadPoolMods) RandomResidentOwnedNotNull(f *faker.Faker) Fileuploa }) } -// Set the model columns to this value -func (m fileuploadPoolMods) ResidentPhone(val null.Val[string]) FileuploadPoolMod { - return FileuploadPoolModFunc(func(_ context.Context, o *FileuploadPoolTemplate) { - o.ResidentPhone = func() null.Val[string] { return val } - }) -} - -// Set the Column from the function -func (m fileuploadPoolMods) ResidentPhoneFunc(f func() null.Val[string]) FileuploadPoolMod { - return FileuploadPoolModFunc(func(_ context.Context, o *FileuploadPoolTemplate) { - o.ResidentPhone = f - }) -} - -// Clear any values for the column -func (m fileuploadPoolMods) UnsetResidentPhone() FileuploadPoolMod { - return FileuploadPoolModFunc(func(_ context.Context, o *FileuploadPoolTemplate) { - o.ResidentPhone = nil - }) -} - -// Generates a random value for the column using the given faker -// if faker is nil, a default faker is used -// The generated value is sometimes null -func (m fileuploadPoolMods) RandomResidentPhone(f *faker.Faker) FileuploadPoolMod { - return FileuploadPoolModFunc(func(_ context.Context, o *FileuploadPoolTemplate) { - o.ResidentPhone = func() null.Val[string] { - if f == nil { - f = &defaultFaker - } - - val := random_string(f) - return null.From(val) - } - }) -} - -// Generates a random value for the column using the given faker -// if faker is nil, a default faker is used -// The generated value is never null -func (m fileuploadPoolMods) RandomResidentPhoneNotNull(f *faker.Faker) FileuploadPoolMod { - return FileuploadPoolModFunc(func(_ context.Context, o *FileuploadPoolTemplate) { - o.ResidentPhone = func() null.Val[string] { - if f == nil { - f = &defaultFaker - } - - val := random_string(f) - return null.From(val) - } - }) -} - // Set the model columns to this value func (m fileuploadPoolMods) Version(val int32) FileuploadPoolMod { return FileuploadPoolModFunc(func(_ context.Context, o *FileuploadPoolTemplate) { @@ -1326,6 +1280,112 @@ func (m fileuploadPoolMods) RandomVersion(f *faker.Faker) FileuploadPoolMod { }) } +// Set the model columns to this value +func (m fileuploadPoolMods) PropertyOwnerPhoneE164(val null.Val[string]) FileuploadPoolMod { + return FileuploadPoolModFunc(func(_ context.Context, o *FileuploadPoolTemplate) { + o.PropertyOwnerPhoneE164 = func() null.Val[string] { return val } + }) +} + +// Set the Column from the function +func (m fileuploadPoolMods) PropertyOwnerPhoneE164Func(f func() null.Val[string]) FileuploadPoolMod { + return FileuploadPoolModFunc(func(_ context.Context, o *FileuploadPoolTemplate) { + o.PropertyOwnerPhoneE164 = f + }) +} + +// Clear any values for the column +func (m fileuploadPoolMods) UnsetPropertyOwnerPhoneE164() FileuploadPoolMod { + return FileuploadPoolModFunc(func(_ context.Context, o *FileuploadPoolTemplate) { + o.PropertyOwnerPhoneE164 = nil + }) +} + +// Generates a random value for the column using the given faker +// if faker is nil, a default faker is used +// The generated value is sometimes null +func (m fileuploadPoolMods) RandomPropertyOwnerPhoneE164(f *faker.Faker) FileuploadPoolMod { + return FileuploadPoolModFunc(func(_ context.Context, o *FileuploadPoolTemplate) { + o.PropertyOwnerPhoneE164 = func() null.Val[string] { + if f == nil { + f = &defaultFaker + } + + val := random_string(f) + return null.From(val) + } + }) +} + +// Generates a random value for the column using the given faker +// if faker is nil, a default faker is used +// The generated value is never null +func (m fileuploadPoolMods) RandomPropertyOwnerPhoneE164NotNull(f *faker.Faker) FileuploadPoolMod { + return FileuploadPoolModFunc(func(_ context.Context, o *FileuploadPoolTemplate) { + o.PropertyOwnerPhoneE164 = func() null.Val[string] { + if f == nil { + f = &defaultFaker + } + + val := random_string(f) + return null.From(val) + } + }) +} + +// Set the model columns to this value +func (m fileuploadPoolMods) ResidentPhoneE164(val null.Val[string]) FileuploadPoolMod { + return FileuploadPoolModFunc(func(_ context.Context, o *FileuploadPoolTemplate) { + o.ResidentPhoneE164 = func() null.Val[string] { return val } + }) +} + +// Set the Column from the function +func (m fileuploadPoolMods) ResidentPhoneE164Func(f func() null.Val[string]) FileuploadPoolMod { + return FileuploadPoolModFunc(func(_ context.Context, o *FileuploadPoolTemplate) { + o.ResidentPhoneE164 = f + }) +} + +// Clear any values for the column +func (m fileuploadPoolMods) UnsetResidentPhoneE164() FileuploadPoolMod { + return FileuploadPoolModFunc(func(_ context.Context, o *FileuploadPoolTemplate) { + o.ResidentPhoneE164 = nil + }) +} + +// Generates a random value for the column using the given faker +// if faker is nil, a default faker is used +// The generated value is sometimes null +func (m fileuploadPoolMods) RandomResidentPhoneE164(f *faker.Faker) FileuploadPoolMod { + return FileuploadPoolModFunc(func(_ context.Context, o *FileuploadPoolTemplate) { + o.ResidentPhoneE164 = func() null.Val[string] { + if f == nil { + f = &defaultFaker + } + + val := random_string(f) + return null.From(val) + } + }) +} + +// Generates a random value for the column using the given faker +// if faker is nil, a default faker is used +// The generated value is never null +func (m fileuploadPoolMods) RandomResidentPhoneE164NotNull(f *faker.Faker) FileuploadPoolMod { + return FileuploadPoolModFunc(func(_ context.Context, o *FileuploadPoolTemplate) { + o.ResidentPhoneE164 = func() null.Val[string] { + if f == nil { + f = &defaultFaker + } + + val := random_string(f) + return null.From(val) + } + }) +} + func (m fileuploadPoolMods) WithParentsCascading() FileuploadPoolMod { return FileuploadPoolModFunc(func(ctx context.Context, o *FileuploadPoolTemplate) { if isDone, _ := fileuploadPoolWithParentsCascadingCtx.Value(ctx); isDone { @@ -1347,6 +1407,16 @@ func (m fileuploadPoolMods) WithParentsCascading() FileuploadPoolMod { related := o.f.NewOrganizationWithContext(ctx, OrganizationMods.WithParentsCascading()) m.WithOrganization(related).Apply(ctx, o) } + { + + related := o.f.NewCommsPhoneWithContext(ctx, CommsPhoneMods.WithParentsCascading()) + m.WithPropertyOwnerPhoneE164Phone(related).Apply(ctx, o) + } + { + + related := o.f.NewCommsPhoneWithContext(ctx, CommsPhoneMods.WithParentsCascading()) + m.WithResidentPhoneE164Phone(related).Apply(ctx, o) + } }) } @@ -1439,3 +1509,63 @@ func (m fileuploadPoolMods) WithoutOrganization() FileuploadPoolMod { o.r.Organization = nil }) } + +func (m fileuploadPoolMods) WithPropertyOwnerPhoneE164Phone(rel *CommsPhoneTemplate) FileuploadPoolMod { + return FileuploadPoolModFunc(func(ctx context.Context, o *FileuploadPoolTemplate) { + o.r.PropertyOwnerPhoneE164Phone = &fileuploadPoolRPropertyOwnerPhoneE164PhoneR{ + o: rel, + } + }) +} + +func (m fileuploadPoolMods) WithNewPropertyOwnerPhoneE164Phone(mods ...CommsPhoneMod) FileuploadPoolMod { + return FileuploadPoolModFunc(func(ctx context.Context, o *FileuploadPoolTemplate) { + related := o.f.NewCommsPhoneWithContext(ctx, mods...) + + m.WithPropertyOwnerPhoneE164Phone(related).Apply(ctx, o) + }) +} + +func (m fileuploadPoolMods) WithExistingPropertyOwnerPhoneE164Phone(em *models.CommsPhone) FileuploadPoolMod { + return FileuploadPoolModFunc(func(ctx context.Context, o *FileuploadPoolTemplate) { + o.r.PropertyOwnerPhoneE164Phone = &fileuploadPoolRPropertyOwnerPhoneE164PhoneR{ + o: o.f.FromExistingCommsPhone(em), + } + }) +} + +func (m fileuploadPoolMods) WithoutPropertyOwnerPhoneE164Phone() FileuploadPoolMod { + return FileuploadPoolModFunc(func(ctx context.Context, o *FileuploadPoolTemplate) { + o.r.PropertyOwnerPhoneE164Phone = nil + }) +} + +func (m fileuploadPoolMods) WithResidentPhoneE164Phone(rel *CommsPhoneTemplate) FileuploadPoolMod { + return FileuploadPoolModFunc(func(ctx context.Context, o *FileuploadPoolTemplate) { + o.r.ResidentPhoneE164Phone = &fileuploadPoolRResidentPhoneE164PhoneR{ + o: rel, + } + }) +} + +func (m fileuploadPoolMods) WithNewResidentPhoneE164Phone(mods ...CommsPhoneMod) FileuploadPoolMod { + return FileuploadPoolModFunc(func(ctx context.Context, o *FileuploadPoolTemplate) { + related := o.f.NewCommsPhoneWithContext(ctx, mods...) + + m.WithResidentPhoneE164Phone(related).Apply(ctx, o) + }) +} + +func (m fileuploadPoolMods) WithExistingResidentPhoneE164Phone(em *models.CommsPhone) FileuploadPoolMod { + return FileuploadPoolModFunc(func(ctx context.Context, o *FileuploadPoolTemplate) { + o.r.ResidentPhoneE164Phone = &fileuploadPoolRResidentPhoneE164PhoneR{ + o: o.f.FromExistingCommsPhone(em), + } + }) +} + +func (m fileuploadPoolMods) WithoutResidentPhoneE164Phone() FileuploadPoolMod { + return FileuploadPoolModFunc(func(ctx context.Context, o *FileuploadPoolTemplate) { + o.r.ResidentPhoneE164Phone = nil + }) +} diff --git a/db/migrations/00062_csv_pool_phone_fix.sql b/db/migrations/00062_csv_pool_phone_fix.sql new file mode 100644 index 00000000..4366ad61 --- /dev/null +++ b/db/migrations/00062_csv_pool_phone_fix.sql @@ -0,0 +1,5 @@ +-- +goose Up +ALTER TABLE fileupload.pool DROP COLUMN property_owner_phone; +ALTER TABLE fileupload.pool DROP COLUMN resident_phone; +ALTER TABLE fileupload.pool ADD COLUMN property_owner_phone_e164 TEXT REFERENCES comms.phone(e164); +ALTER TABLE fileupload.pool ADD COLUMN resident_phone_e164 TEXT REFERENCES comms.phone(e164); diff --git a/db/models/comms.phone.bob.go b/db/models/comms.phone.bob.go index 4e4045e4..de5be9b7 100644 --- a/db/models/comms.phone.bob.go +++ b/db/models/comms.phone.bob.go @@ -21,6 +21,7 @@ import ( "github.com/Gleipnir-Technology/bob/types/pgtypes" enums "github.com/Gleipnir-Technology/nidus-sync/db/enums" "github.com/aarondl/opt/omit" + "github.com/aarondl/opt/omitnull" "github.com/stephenafamo/scan" ) @@ -51,6 +52,8 @@ type commsPhoneR struct { DestinationTextLogs CommsTextLogSlice // comms.text_log.text_log_destination_fkey SourceTextLogs CommsTextLogSlice // comms.text_log.text_log_source_fkey Organizations OrganizationSlice // district_subscription_phone.district_subscription_phone_organization_id_fkeydistrict_subscription_phone.district_subscription_phone_phone_e164_fkey + PropertyOwnerPhoneE164Pools FileuploadPoolSlice // fileupload.pool.pool_property_owner_phone_e164_fkey + ResidentPhoneE164Pools FileuploadPoolSlice // fileupload.pool.pool_resident_phone_e164_fkey PhoneE164NotifyPhoneNuisances PublicreportNotifyPhoneNuisanceSlice // publicreport.notify_phone_nuisance.notify_phone_nuisance_phone_e164_fkey PhoneE164NotifyPhonePools PublicreportNotifyPhonePoolSlice // publicreport.notify_phone_pool.notify_phone_pool_phone_e164_fkey PhoneE164SubscribePhones PublicreportSubscribePhoneSlice // publicreport.subscribe_phone.subscribe_phone_phone_e164_fkey @@ -503,6 +506,54 @@ func (os CommsPhoneSlice) Organizations(mods ...bob.Mod[*dialect.SelectQuery]) O )...) } +// PropertyOwnerPhoneE164Pools starts a query for related objects on fileupload.pool +func (o *CommsPhone) PropertyOwnerPhoneE164Pools(mods ...bob.Mod[*dialect.SelectQuery]) FileuploadPoolsQuery { + return FileuploadPools.Query(append(mods, + sm.Where(FileuploadPools.Columns.PropertyOwnerPhoneE164.EQ(psql.Arg(o.E164))), + )...) +} + +func (os CommsPhoneSlice) PropertyOwnerPhoneE164Pools(mods ...bob.Mod[*dialect.SelectQuery]) FileuploadPoolsQuery { + pkE164 := make(pgtypes.Array[string], 0, len(os)) + for _, o := range os { + if o == nil { + continue + } + pkE164 = append(pkE164, o.E164) + } + PKArgExpr := psql.Select(sm.Columns( + psql.F("unnest", psql.Cast(psql.Arg(pkE164), "text[]")), + )) + + return FileuploadPools.Query(append(mods, + sm.Where(psql.Group(FileuploadPools.Columns.PropertyOwnerPhoneE164).OP("IN", PKArgExpr)), + )...) +} + +// ResidentPhoneE164Pools starts a query for related objects on fileupload.pool +func (o *CommsPhone) ResidentPhoneE164Pools(mods ...bob.Mod[*dialect.SelectQuery]) FileuploadPoolsQuery { + return FileuploadPools.Query(append(mods, + sm.Where(FileuploadPools.Columns.ResidentPhoneE164.EQ(psql.Arg(o.E164))), + )...) +} + +func (os CommsPhoneSlice) ResidentPhoneE164Pools(mods ...bob.Mod[*dialect.SelectQuery]) FileuploadPoolsQuery { + pkE164 := make(pgtypes.Array[string], 0, len(os)) + for _, o := range os { + if o == nil { + continue + } + pkE164 = append(pkE164, o.E164) + } + PKArgExpr := psql.Select(sm.Columns( + psql.F("unnest", psql.Cast(psql.Arg(pkE164), "text[]")), + )) + + return FileuploadPools.Query(append(mods, + sm.Where(psql.Group(FileuploadPools.Columns.ResidentPhoneE164).OP("IN", PKArgExpr)), + )...) +} + // PhoneE164NotifyPhoneNuisances starts a query for related objects on publicreport.notify_phone_nuisance func (o *CommsPhone) PhoneE164NotifyPhoneNuisances(mods ...bob.Mod[*dialect.SelectQuery]) PublicreportNotifyPhoneNuisancesQuery { return PublicreportNotifyPhoneNuisances.Query(append(mods, @@ -844,6 +895,142 @@ func (commsPhone0 *CommsPhone) AttachOrganizations(ctx context.Context, exec bob return nil } +func insertCommsPhonePropertyOwnerPhoneE164Pools0(ctx context.Context, exec bob.Executor, fileuploadPools1 []*FileuploadPoolSetter, commsPhone0 *CommsPhone) (FileuploadPoolSlice, error) { + for i := range fileuploadPools1 { + fileuploadPools1[i].PropertyOwnerPhoneE164 = omitnull.From(commsPhone0.E164) + } + + ret, err := FileuploadPools.Insert(bob.ToMods(fileuploadPools1...)).All(ctx, exec) + if err != nil { + return ret, fmt.Errorf("insertCommsPhonePropertyOwnerPhoneE164Pools0: %w", err) + } + + return ret, nil +} + +func attachCommsPhonePropertyOwnerPhoneE164Pools0(ctx context.Context, exec bob.Executor, count int, fileuploadPools1 FileuploadPoolSlice, commsPhone0 *CommsPhone) (FileuploadPoolSlice, error) { + setter := &FileuploadPoolSetter{ + PropertyOwnerPhoneE164: omitnull.From(commsPhone0.E164), + } + + err := fileuploadPools1.UpdateAll(ctx, exec, *setter) + if err != nil { + return nil, fmt.Errorf("attachCommsPhonePropertyOwnerPhoneE164Pools0: %w", err) + } + + return fileuploadPools1, nil +} + +func (commsPhone0 *CommsPhone) InsertPropertyOwnerPhoneE164Pools(ctx context.Context, exec bob.Executor, related ...*FileuploadPoolSetter) error { + if len(related) == 0 { + return nil + } + + var err error + + fileuploadPools1, err := insertCommsPhonePropertyOwnerPhoneE164Pools0(ctx, exec, related, commsPhone0) + if err != nil { + return err + } + + commsPhone0.R.PropertyOwnerPhoneE164Pools = append(commsPhone0.R.PropertyOwnerPhoneE164Pools, fileuploadPools1...) + + for _, rel := range fileuploadPools1 { + rel.R.PropertyOwnerPhoneE164Phone = commsPhone0 + } + return nil +} + +func (commsPhone0 *CommsPhone) AttachPropertyOwnerPhoneE164Pools(ctx context.Context, exec bob.Executor, related ...*FileuploadPool) error { + if len(related) == 0 { + return nil + } + + var err error + fileuploadPools1 := FileuploadPoolSlice(related) + + _, err = attachCommsPhonePropertyOwnerPhoneE164Pools0(ctx, exec, len(related), fileuploadPools1, commsPhone0) + if err != nil { + return err + } + + commsPhone0.R.PropertyOwnerPhoneE164Pools = append(commsPhone0.R.PropertyOwnerPhoneE164Pools, fileuploadPools1...) + + for _, rel := range related { + rel.R.PropertyOwnerPhoneE164Phone = commsPhone0 + } + + return nil +} + +func insertCommsPhoneResidentPhoneE164Pools0(ctx context.Context, exec bob.Executor, fileuploadPools1 []*FileuploadPoolSetter, commsPhone0 *CommsPhone) (FileuploadPoolSlice, error) { + for i := range fileuploadPools1 { + fileuploadPools1[i].ResidentPhoneE164 = omitnull.From(commsPhone0.E164) + } + + ret, err := FileuploadPools.Insert(bob.ToMods(fileuploadPools1...)).All(ctx, exec) + if err != nil { + return ret, fmt.Errorf("insertCommsPhoneResidentPhoneE164Pools0: %w", err) + } + + return ret, nil +} + +func attachCommsPhoneResidentPhoneE164Pools0(ctx context.Context, exec bob.Executor, count int, fileuploadPools1 FileuploadPoolSlice, commsPhone0 *CommsPhone) (FileuploadPoolSlice, error) { + setter := &FileuploadPoolSetter{ + ResidentPhoneE164: omitnull.From(commsPhone0.E164), + } + + err := fileuploadPools1.UpdateAll(ctx, exec, *setter) + if err != nil { + return nil, fmt.Errorf("attachCommsPhoneResidentPhoneE164Pools0: %w", err) + } + + return fileuploadPools1, nil +} + +func (commsPhone0 *CommsPhone) InsertResidentPhoneE164Pools(ctx context.Context, exec bob.Executor, related ...*FileuploadPoolSetter) error { + if len(related) == 0 { + return nil + } + + var err error + + fileuploadPools1, err := insertCommsPhoneResidentPhoneE164Pools0(ctx, exec, related, commsPhone0) + if err != nil { + return err + } + + commsPhone0.R.ResidentPhoneE164Pools = append(commsPhone0.R.ResidentPhoneE164Pools, fileuploadPools1...) + + for _, rel := range fileuploadPools1 { + rel.R.ResidentPhoneE164Phone = commsPhone0 + } + return nil +} + +func (commsPhone0 *CommsPhone) AttachResidentPhoneE164Pools(ctx context.Context, exec bob.Executor, related ...*FileuploadPool) error { + if len(related) == 0 { + return nil + } + + var err error + fileuploadPools1 := FileuploadPoolSlice(related) + + _, err = attachCommsPhoneResidentPhoneE164Pools0(ctx, exec, len(related), fileuploadPools1, commsPhone0) + if err != nil { + return err + } + + commsPhone0.R.ResidentPhoneE164Pools = append(commsPhone0.R.ResidentPhoneE164Pools, fileuploadPools1...) + + for _, rel := range related { + rel.R.ResidentPhoneE164Phone = commsPhone0 + } + + return nil +} + func insertCommsPhonePhoneE164NotifyPhoneNuisances0(ctx context.Context, exec bob.Executor, publicreportNotifyPhoneNuisances1 []*PublicreportNotifyPhoneNuisanceSetter, commsPhone0 *CommsPhone) (PublicreportNotifyPhoneNuisanceSlice, error) { for i := range publicreportNotifyPhoneNuisances1 { publicreportNotifyPhoneNuisances1[i].PhoneE164 = omit.From(commsPhone0.E164) @@ -1128,6 +1315,34 @@ func (o *CommsPhone) Preload(name string, retrieved any) error { } } return nil + case "PropertyOwnerPhoneE164Pools": + rels, ok := retrieved.(FileuploadPoolSlice) + if !ok { + return fmt.Errorf("commsPhone cannot load %T as %q", retrieved, name) + } + + o.R.PropertyOwnerPhoneE164Pools = rels + + for _, rel := range rels { + if rel != nil { + rel.R.PropertyOwnerPhoneE164Phone = o + } + } + return nil + case "ResidentPhoneE164Pools": + rels, ok := retrieved.(FileuploadPoolSlice) + if !ok { + return fmt.Errorf("commsPhone cannot load %T as %q", retrieved, name) + } + + o.R.ResidentPhoneE164Pools = rels + + for _, rel := range rels { + if rel != nil { + rel.R.ResidentPhoneE164Phone = o + } + } + return nil case "PhoneE164NotifyPhoneNuisances": rels, ok := retrieved.(PublicreportNotifyPhoneNuisanceSlice) if !ok { @@ -1186,6 +1401,8 @@ type commsPhoneThenLoader[Q orm.Loadable] struct { DestinationTextLogs func(...bob.Mod[*dialect.SelectQuery]) orm.Loader[Q] SourceTextLogs func(...bob.Mod[*dialect.SelectQuery]) orm.Loader[Q] Organizations func(...bob.Mod[*dialect.SelectQuery]) orm.Loader[Q] + PropertyOwnerPhoneE164Pools func(...bob.Mod[*dialect.SelectQuery]) orm.Loader[Q] + ResidentPhoneE164Pools func(...bob.Mod[*dialect.SelectQuery]) orm.Loader[Q] PhoneE164NotifyPhoneNuisances func(...bob.Mod[*dialect.SelectQuery]) orm.Loader[Q] PhoneE164NotifyPhonePools func(...bob.Mod[*dialect.SelectQuery]) orm.Loader[Q] PhoneE164SubscribePhones func(...bob.Mod[*dialect.SelectQuery]) orm.Loader[Q] @@ -1204,6 +1421,12 @@ func buildCommsPhoneThenLoader[Q orm.Loadable]() commsPhoneThenLoader[Q] { type OrganizationsLoadInterface interface { LoadOrganizations(context.Context, bob.Executor, ...bob.Mod[*dialect.SelectQuery]) error } + type PropertyOwnerPhoneE164PoolsLoadInterface interface { + LoadPropertyOwnerPhoneE164Pools(context.Context, bob.Executor, ...bob.Mod[*dialect.SelectQuery]) error + } + type ResidentPhoneE164PoolsLoadInterface interface { + LoadResidentPhoneE164Pools(context.Context, bob.Executor, ...bob.Mod[*dialect.SelectQuery]) error + } type PhoneE164NotifyPhoneNuisancesLoadInterface interface { LoadPhoneE164NotifyPhoneNuisances(context.Context, bob.Executor, ...bob.Mod[*dialect.SelectQuery]) error } @@ -1239,6 +1462,18 @@ func buildCommsPhoneThenLoader[Q orm.Loadable]() commsPhoneThenLoader[Q] { return retrieved.LoadOrganizations(ctx, exec, mods...) }, ), + PropertyOwnerPhoneE164Pools: thenLoadBuilder[Q]( + "PropertyOwnerPhoneE164Pools", + func(ctx context.Context, exec bob.Executor, retrieved PropertyOwnerPhoneE164PoolsLoadInterface, mods ...bob.Mod[*dialect.SelectQuery]) error { + return retrieved.LoadPropertyOwnerPhoneE164Pools(ctx, exec, mods...) + }, + ), + ResidentPhoneE164Pools: thenLoadBuilder[Q]( + "ResidentPhoneE164Pools", + func(ctx context.Context, exec bob.Executor, retrieved ResidentPhoneE164PoolsLoadInterface, mods ...bob.Mod[*dialect.SelectQuery]) error { + return retrieved.LoadResidentPhoneE164Pools(ctx, exec, mods...) + }, + ), PhoneE164NotifyPhoneNuisances: thenLoadBuilder[Q]( "PhoneE164NotifyPhoneNuisances", func(ctx context.Context, exec bob.Executor, retrieved PhoneE164NotifyPhoneNuisancesLoadInterface, mods ...bob.Mod[*dialect.SelectQuery]) error { @@ -1524,6 +1759,134 @@ func (os CommsPhoneSlice) LoadOrganizations(ctx context.Context, exec bob.Execut return nil } +// LoadPropertyOwnerPhoneE164Pools loads the commsPhone's PropertyOwnerPhoneE164Pools into the .R struct +func (o *CommsPhone) LoadPropertyOwnerPhoneE164Pools(ctx context.Context, exec bob.Executor, mods ...bob.Mod[*dialect.SelectQuery]) error { + if o == nil { + return nil + } + + // Reset the relationship + o.R.PropertyOwnerPhoneE164Pools = nil + + related, err := o.PropertyOwnerPhoneE164Pools(mods...).All(ctx, exec) + if err != nil { + return err + } + + for _, rel := range related { + rel.R.PropertyOwnerPhoneE164Phone = o + } + + o.R.PropertyOwnerPhoneE164Pools = related + return nil +} + +// LoadPropertyOwnerPhoneE164Pools loads the commsPhone's PropertyOwnerPhoneE164Pools into the .R struct +func (os CommsPhoneSlice) LoadPropertyOwnerPhoneE164Pools(ctx context.Context, exec bob.Executor, mods ...bob.Mod[*dialect.SelectQuery]) error { + if len(os) == 0 { + return nil + } + + fileuploadPools, err := os.PropertyOwnerPhoneE164Pools(mods...).All(ctx, exec) + if err != nil { + return err + } + + for _, o := range os { + if o == nil { + continue + } + + o.R.PropertyOwnerPhoneE164Pools = nil + } + + for _, o := range os { + if o == nil { + continue + } + + for _, rel := range fileuploadPools { + + if !rel.PropertyOwnerPhoneE164.IsValue() { + continue + } + if !(rel.PropertyOwnerPhoneE164.IsValue() && o.E164 == rel.PropertyOwnerPhoneE164.MustGet()) { + continue + } + + rel.R.PropertyOwnerPhoneE164Phone = o + + o.R.PropertyOwnerPhoneE164Pools = append(o.R.PropertyOwnerPhoneE164Pools, rel) + } + } + + return nil +} + +// LoadResidentPhoneE164Pools loads the commsPhone's ResidentPhoneE164Pools into the .R struct +func (o *CommsPhone) LoadResidentPhoneE164Pools(ctx context.Context, exec bob.Executor, mods ...bob.Mod[*dialect.SelectQuery]) error { + if o == nil { + return nil + } + + // Reset the relationship + o.R.ResidentPhoneE164Pools = nil + + related, err := o.ResidentPhoneE164Pools(mods...).All(ctx, exec) + if err != nil { + return err + } + + for _, rel := range related { + rel.R.ResidentPhoneE164Phone = o + } + + o.R.ResidentPhoneE164Pools = related + return nil +} + +// LoadResidentPhoneE164Pools loads the commsPhone's ResidentPhoneE164Pools into the .R struct +func (os CommsPhoneSlice) LoadResidentPhoneE164Pools(ctx context.Context, exec bob.Executor, mods ...bob.Mod[*dialect.SelectQuery]) error { + if len(os) == 0 { + return nil + } + + fileuploadPools, err := os.ResidentPhoneE164Pools(mods...).All(ctx, exec) + if err != nil { + return err + } + + for _, o := range os { + if o == nil { + continue + } + + o.R.ResidentPhoneE164Pools = nil + } + + for _, o := range os { + if o == nil { + continue + } + + for _, rel := range fileuploadPools { + + if !rel.ResidentPhoneE164.IsValue() { + continue + } + if !(rel.ResidentPhoneE164.IsValue() && o.E164 == rel.ResidentPhoneE164.MustGet()) { + continue + } + + rel.R.ResidentPhoneE164Phone = o + + o.R.ResidentPhoneE164Pools = append(o.R.ResidentPhoneE164Pools, rel) + } + } + + return nil +} + // LoadPhoneE164NotifyPhoneNuisances loads the commsPhone's PhoneE164NotifyPhoneNuisances into the .R struct func (o *CommsPhone) LoadPhoneE164NotifyPhoneNuisances(ctx context.Context, exec bob.Executor, mods ...bob.Mod[*dialect.SelectQuery]) error { if o == nil { @@ -1713,6 +2076,8 @@ type commsPhoneC struct { DestinationTextLogs *int64 SourceTextLogs *int64 Organizations *int64 + PropertyOwnerPhoneE164Pools *int64 + ResidentPhoneE164Pools *int64 PhoneE164NotifyPhoneNuisances *int64 PhoneE164NotifyPhonePools *int64 PhoneE164SubscribePhones *int64 @@ -1733,6 +2098,10 @@ func (o *CommsPhone) PreloadCount(name string, count int64) error { o.C.SourceTextLogs = &count case "Organizations": o.C.Organizations = &count + case "PropertyOwnerPhoneE164Pools": + o.C.PropertyOwnerPhoneE164Pools = &count + case "ResidentPhoneE164Pools": + o.C.ResidentPhoneE164Pools = &count case "PhoneE164NotifyPhoneNuisances": o.C.PhoneE164NotifyPhoneNuisances = &count case "PhoneE164NotifyPhonePools": @@ -1748,6 +2117,8 @@ type commsPhoneCountPreloader struct { DestinationTextLogs func(...bob.Mod[*dialect.SelectQuery]) psql.Preloader SourceTextLogs func(...bob.Mod[*dialect.SelectQuery]) psql.Preloader Organizations func(...bob.Mod[*dialect.SelectQuery]) psql.Preloader + PropertyOwnerPhoneE164Pools func(...bob.Mod[*dialect.SelectQuery]) psql.Preloader + ResidentPhoneE164Pools func(...bob.Mod[*dialect.SelectQuery]) psql.Preloader PhoneE164NotifyPhoneNuisances func(...bob.Mod[*dialect.SelectQuery]) psql.Preloader PhoneE164NotifyPhonePools func(...bob.Mod[*dialect.SelectQuery]) psql.Preloader PhoneE164SubscribePhones func(...bob.Mod[*dialect.SelectQuery]) psql.Preloader @@ -1826,6 +2197,40 @@ func buildCommsPhoneCountPreloader() commsPhoneCountPreloader { return psql.Group(psql.Select(subqueryMods...).Expression) }) }, + PropertyOwnerPhoneE164Pools: func(mods ...bob.Mod[*dialect.SelectQuery]) psql.Preloader { + return countPreloader[*CommsPhone]("PropertyOwnerPhoneE164Pools", func(parent string) bob.Expression { + // Build a correlated subquery: (SELECT COUNT(*) FROM related WHERE fk = parent.pk) + if parent == "" { + parent = CommsPhones.Alias() + } + + subqueryMods := []bob.Mod[*dialect.SelectQuery]{ + sm.Columns(psql.Raw("count(*)")), + + sm.From(FileuploadPools.Name()), + sm.Where(psql.Quote(FileuploadPools.Alias(), "property_owner_phone_e164").EQ(psql.Quote(parent, "e164"))), + } + subqueryMods = append(subqueryMods, mods...) + return psql.Group(psql.Select(subqueryMods...).Expression) + }) + }, + ResidentPhoneE164Pools: func(mods ...bob.Mod[*dialect.SelectQuery]) psql.Preloader { + return countPreloader[*CommsPhone]("ResidentPhoneE164Pools", func(parent string) bob.Expression { + // Build a correlated subquery: (SELECT COUNT(*) FROM related WHERE fk = parent.pk) + if parent == "" { + parent = CommsPhones.Alias() + } + + subqueryMods := []bob.Mod[*dialect.SelectQuery]{ + sm.Columns(psql.Raw("count(*)")), + + sm.From(FileuploadPools.Name()), + sm.Where(psql.Quote(FileuploadPools.Alias(), "resident_phone_e164").EQ(psql.Quote(parent, "e164"))), + } + subqueryMods = append(subqueryMods, mods...) + return psql.Group(psql.Select(subqueryMods...).Expression) + }) + }, PhoneE164NotifyPhoneNuisances: func(mods ...bob.Mod[*dialect.SelectQuery]) psql.Preloader { return countPreloader[*CommsPhone]("PhoneE164NotifyPhoneNuisances", func(parent string) bob.Expression { // Build a correlated subquery: (SELECT COUNT(*) FROM related WHERE fk = parent.pk) @@ -1885,6 +2290,8 @@ type commsPhoneCountThenLoader[Q orm.Loadable] struct { DestinationTextLogs func(...bob.Mod[*dialect.SelectQuery]) orm.Loader[Q] SourceTextLogs func(...bob.Mod[*dialect.SelectQuery]) orm.Loader[Q] Organizations func(...bob.Mod[*dialect.SelectQuery]) orm.Loader[Q] + PropertyOwnerPhoneE164Pools func(...bob.Mod[*dialect.SelectQuery]) orm.Loader[Q] + ResidentPhoneE164Pools func(...bob.Mod[*dialect.SelectQuery]) orm.Loader[Q] PhoneE164NotifyPhoneNuisances func(...bob.Mod[*dialect.SelectQuery]) orm.Loader[Q] PhoneE164NotifyPhonePools func(...bob.Mod[*dialect.SelectQuery]) orm.Loader[Q] PhoneE164SubscribePhones func(...bob.Mod[*dialect.SelectQuery]) orm.Loader[Q] @@ -1903,6 +2310,12 @@ func buildCommsPhoneCountThenLoader[Q orm.Loadable]() commsPhoneCountThenLoader[ type OrganizationsCountInterface interface { LoadCountOrganizations(context.Context, bob.Executor, ...bob.Mod[*dialect.SelectQuery]) error } + type PropertyOwnerPhoneE164PoolsCountInterface interface { + LoadCountPropertyOwnerPhoneE164Pools(context.Context, bob.Executor, ...bob.Mod[*dialect.SelectQuery]) error + } + type ResidentPhoneE164PoolsCountInterface interface { + LoadCountResidentPhoneE164Pools(context.Context, bob.Executor, ...bob.Mod[*dialect.SelectQuery]) error + } type PhoneE164NotifyPhoneNuisancesCountInterface interface { LoadCountPhoneE164NotifyPhoneNuisances(context.Context, bob.Executor, ...bob.Mod[*dialect.SelectQuery]) error } @@ -1938,6 +2351,18 @@ func buildCommsPhoneCountThenLoader[Q orm.Loadable]() commsPhoneCountThenLoader[ return retrieved.LoadCountOrganizations(ctx, exec, mods...) }, ), + PropertyOwnerPhoneE164Pools: countThenLoadBuilder[Q]( + "PropertyOwnerPhoneE164Pools", + func(ctx context.Context, exec bob.Executor, retrieved PropertyOwnerPhoneE164PoolsCountInterface, mods ...bob.Mod[*dialect.SelectQuery]) error { + return retrieved.LoadCountPropertyOwnerPhoneE164Pools(ctx, exec, mods...) + }, + ), + ResidentPhoneE164Pools: countThenLoadBuilder[Q]( + "ResidentPhoneE164Pools", + func(ctx context.Context, exec bob.Executor, retrieved ResidentPhoneE164PoolsCountInterface, mods ...bob.Mod[*dialect.SelectQuery]) error { + return retrieved.LoadCountResidentPhoneE164Pools(ctx, exec, mods...) + }, + ), PhoneE164NotifyPhoneNuisances: countThenLoadBuilder[Q]( "PhoneE164NotifyPhoneNuisances", func(ctx context.Context, exec bob.Executor, retrieved PhoneE164NotifyPhoneNuisancesCountInterface, mods ...bob.Mod[*dialect.SelectQuery]) error { @@ -2079,6 +2504,66 @@ func (os CommsPhoneSlice) LoadCountOrganizations(ctx context.Context, exec bob.E return nil } +// LoadCountPropertyOwnerPhoneE164Pools loads the count of PropertyOwnerPhoneE164Pools into the C struct +func (o *CommsPhone) LoadCountPropertyOwnerPhoneE164Pools(ctx context.Context, exec bob.Executor, mods ...bob.Mod[*dialect.SelectQuery]) error { + if o == nil { + return nil + } + + count, err := o.PropertyOwnerPhoneE164Pools(mods...).Count(ctx, exec) + if err != nil { + return err + } + + o.C.PropertyOwnerPhoneE164Pools = &count + return nil +} + +// LoadCountPropertyOwnerPhoneE164Pools loads the count of PropertyOwnerPhoneE164Pools for a slice +func (os CommsPhoneSlice) LoadCountPropertyOwnerPhoneE164Pools(ctx context.Context, exec bob.Executor, mods ...bob.Mod[*dialect.SelectQuery]) error { + if len(os) == 0 { + return nil + } + + for _, o := range os { + if err := o.LoadCountPropertyOwnerPhoneE164Pools(ctx, exec, mods...); err != nil { + return err + } + } + + return nil +} + +// LoadCountResidentPhoneE164Pools loads the count of ResidentPhoneE164Pools into the C struct +func (o *CommsPhone) LoadCountResidentPhoneE164Pools(ctx context.Context, exec bob.Executor, mods ...bob.Mod[*dialect.SelectQuery]) error { + if o == nil { + return nil + } + + count, err := o.ResidentPhoneE164Pools(mods...).Count(ctx, exec) + if err != nil { + return err + } + + o.C.ResidentPhoneE164Pools = &count + return nil +} + +// LoadCountResidentPhoneE164Pools loads the count of ResidentPhoneE164Pools for a slice +func (os CommsPhoneSlice) LoadCountResidentPhoneE164Pools(ctx context.Context, exec bob.Executor, mods ...bob.Mod[*dialect.SelectQuery]) error { + if len(os) == 0 { + return nil + } + + for _, o := range os { + if err := o.LoadCountResidentPhoneE164Pools(ctx, exec, mods...); err != nil { + return err + } + } + + return nil +} + // LoadCountPhoneE164NotifyPhoneNuisances loads the count of PhoneE164NotifyPhoneNuisances into the C struct func (o *CommsPhone) LoadCountPhoneE164NotifyPhoneNuisances(ctx context.Context, exec bob.Executor, mods ...bob.Mod[*dialect.SelectQuery]) error { if o == nil { @@ -2175,6 +2660,8 @@ type commsPhoneJoins[Q dialect.Joinable] struct { DestinationTextLogs modAs[Q, commsTextLogColumns] SourceTextLogs modAs[Q, commsTextLogColumns] Organizations modAs[Q, organizationColumns] + PropertyOwnerPhoneE164Pools modAs[Q, fileuploadPoolColumns] + ResidentPhoneE164Pools modAs[Q, fileuploadPoolColumns] PhoneE164NotifyPhoneNuisances modAs[Q, publicreportNotifyPhoneNuisanceColumns] PhoneE164NotifyPhonePools modAs[Q, publicreportNotifyPhonePoolColumns] PhoneE164SubscribePhones modAs[Q, publicreportSubscribePhoneColumns] @@ -2251,6 +2738,34 @@ func buildCommsPhoneJoins[Q dialect.Joinable](cols commsPhoneColumns, typ string return mods }, }, + PropertyOwnerPhoneE164Pools: modAs[Q, fileuploadPoolColumns]{ + c: FileuploadPools.Columns, + f: func(to fileuploadPoolColumns) bob.Mod[Q] { + mods := make(mods.QueryMods[Q], 0, 1) + + { + mods = append(mods, dialect.Join[Q](typ, FileuploadPools.Name().As(to.Alias())).On( + to.PropertyOwnerPhoneE164.EQ(cols.E164), + )) + } + + return mods + }, + }, + ResidentPhoneE164Pools: modAs[Q, fileuploadPoolColumns]{ + c: FileuploadPools.Columns, + f: func(to fileuploadPoolColumns) bob.Mod[Q] { + mods := make(mods.QueryMods[Q], 0, 1) + + { + mods = append(mods, dialect.Join[Q](typ, FileuploadPools.Name().As(to.Alias())).On( + to.ResidentPhoneE164.EQ(cols.E164), + )) + } + + return mods + }, + }, PhoneE164NotifyPhoneNuisances: modAs[Q, publicreportNotifyPhoneNuisanceColumns]{ c: PublicreportNotifyPhoneNuisances.Columns, f: func(to publicreportNotifyPhoneNuisanceColumns) bob.Mod[Q] { diff --git a/db/models/fileupload.pool.bob.go b/db/models/fileupload.pool.bob.go index 483286d5..d4127405 100644 --- a/db/models/fileupload.pool.bob.go +++ b/db/models/fileupload.pool.bob.go @@ -27,27 +27,27 @@ import ( // FileuploadPool is an object representing the database table. type FileuploadPool struct { - AddressCity string `db:"address_city" ` - AddressPostalCode string `db:"address_postal_code" ` - AddressStreet string `db:"address_street" ` - Committed bool `db:"committed" ` - Condition enums.FileuploadPoolconditiontype `db:"condition" ` - Created time.Time `db:"created" ` - CreatorID int32 `db:"creator_id" ` - CSVFile int32 `db:"csv_file" ` - Deleted null.Val[time.Time] `db:"deleted" ` - Geom null.Val[string] `db:"geom" ` - H3cell null.Val[string] `db:"h3cell" ` - ID int32 `db:"id,pk" ` - IsInDistrict bool `db:"is_in_district" ` - IsNew bool `db:"is_new" ` - Notes string `db:"notes" ` - OrganizationID int32 `db:"organization_id" ` - PropertyOwnerName string `db:"property_owner_name" ` - PropertyOwnerPhone null.Val[string] `db:"property_owner_phone" ` - ResidentOwned null.Val[bool] `db:"resident_owned" ` - ResidentPhone null.Val[string] `db:"resident_phone" ` - Version int32 `db:"version,pk" ` + AddressCity string `db:"address_city" ` + AddressPostalCode string `db:"address_postal_code" ` + AddressStreet string `db:"address_street" ` + Committed bool `db:"committed" ` + Condition enums.FileuploadPoolconditiontype `db:"condition" ` + Created time.Time `db:"created" ` + CreatorID int32 `db:"creator_id" ` + CSVFile int32 `db:"csv_file" ` + Deleted null.Val[time.Time] `db:"deleted" ` + Geom null.Val[string] `db:"geom" ` + H3cell null.Val[string] `db:"h3cell" ` + ID int32 `db:"id,pk" ` + IsInDistrict bool `db:"is_in_district" ` + IsNew bool `db:"is_new" ` + Notes string `db:"notes" ` + OrganizationID int32 `db:"organization_id" ` + PropertyOwnerName string `db:"property_owner_name" ` + ResidentOwned null.Val[bool] `db:"resident_owned" ` + Version int32 `db:"version,pk" ` + PropertyOwnerPhoneE164 null.Val[string] `db:"property_owner_phone_e164" ` + ResidentPhoneE164 null.Val[string] `db:"resident_phone_e164" ` R fileuploadPoolR `db:"-" ` } @@ -64,65 +64,67 @@ type FileuploadPoolsQuery = *psql.ViewQuery[*FileuploadPool, FileuploadPoolSlice // fileuploadPoolR is where relationships are stored. type fileuploadPoolR struct { - CreatorUser *User // fileupload.pool.pool_creator_id_fkey - CSVFileCSV *FileuploadCSV // fileupload.pool.pool_csv_file_fkey - Organization *Organization // fileupload.pool.pool_organization_id_fkey + CreatorUser *User // fileupload.pool.pool_creator_id_fkey + CSVFileCSV *FileuploadCSV // fileupload.pool.pool_csv_file_fkey + Organization *Organization // fileupload.pool.pool_organization_id_fkey + PropertyOwnerPhoneE164Phone *CommsPhone // fileupload.pool.pool_property_owner_phone_e164_fkey + ResidentPhoneE164Phone *CommsPhone // fileupload.pool.pool_resident_phone_e164_fkey } func buildFileuploadPoolColumns(alias string) fileuploadPoolColumns { return fileuploadPoolColumns{ ColumnsExpr: expr.NewColumnsExpr( - "address_city", "address_postal_code", "address_street", "committed", "condition", "created", "creator_id", "csv_file", "deleted", "geom", "h3cell", "id", "is_in_district", "is_new", "notes", "organization_id", "property_owner_name", "property_owner_phone", "resident_owned", "resident_phone", "version", + "address_city", "address_postal_code", "address_street", "committed", "condition", "created", "creator_id", "csv_file", "deleted", "geom", "h3cell", "id", "is_in_district", "is_new", "notes", "organization_id", "property_owner_name", "resident_owned", "version", "property_owner_phone_e164", "resident_phone_e164", ).WithParent("fileupload.pool"), - tableAlias: alias, - AddressCity: psql.Quote(alias, "address_city"), - AddressPostalCode: psql.Quote(alias, "address_postal_code"), - AddressStreet: psql.Quote(alias, "address_street"), - Committed: psql.Quote(alias, "committed"), - Condition: psql.Quote(alias, "condition"), - Created: psql.Quote(alias, "created"), - CreatorID: psql.Quote(alias, "creator_id"), - CSVFile: psql.Quote(alias, "csv_file"), - Deleted: psql.Quote(alias, "deleted"), - Geom: psql.Quote(alias, "geom"), - H3cell: psql.Quote(alias, "h3cell"), - ID: psql.Quote(alias, "id"), - IsInDistrict: psql.Quote(alias, "is_in_district"), - IsNew: psql.Quote(alias, "is_new"), - Notes: psql.Quote(alias, "notes"), - OrganizationID: psql.Quote(alias, "organization_id"), - PropertyOwnerName: psql.Quote(alias, "property_owner_name"), - PropertyOwnerPhone: psql.Quote(alias, "property_owner_phone"), - ResidentOwned: psql.Quote(alias, "resident_owned"), - ResidentPhone: psql.Quote(alias, "resident_phone"), - Version: psql.Quote(alias, "version"), + tableAlias: alias, + AddressCity: psql.Quote(alias, "address_city"), + AddressPostalCode: psql.Quote(alias, "address_postal_code"), + AddressStreet: psql.Quote(alias, "address_street"), + Committed: psql.Quote(alias, "committed"), + Condition: psql.Quote(alias, "condition"), + Created: psql.Quote(alias, "created"), + CreatorID: psql.Quote(alias, "creator_id"), + CSVFile: psql.Quote(alias, "csv_file"), + Deleted: psql.Quote(alias, "deleted"), + Geom: psql.Quote(alias, "geom"), + H3cell: psql.Quote(alias, "h3cell"), + ID: psql.Quote(alias, "id"), + IsInDistrict: psql.Quote(alias, "is_in_district"), + IsNew: psql.Quote(alias, "is_new"), + Notes: psql.Quote(alias, "notes"), + OrganizationID: psql.Quote(alias, "organization_id"), + PropertyOwnerName: psql.Quote(alias, "property_owner_name"), + ResidentOwned: psql.Quote(alias, "resident_owned"), + Version: psql.Quote(alias, "version"), + PropertyOwnerPhoneE164: psql.Quote(alias, "property_owner_phone_e164"), + ResidentPhoneE164: psql.Quote(alias, "resident_phone_e164"), } } type fileuploadPoolColumns struct { expr.ColumnsExpr - tableAlias string - AddressCity psql.Expression - AddressPostalCode psql.Expression - AddressStreet psql.Expression - Committed psql.Expression - Condition psql.Expression - Created psql.Expression - CreatorID psql.Expression - CSVFile psql.Expression - Deleted psql.Expression - Geom psql.Expression - H3cell psql.Expression - ID psql.Expression - IsInDistrict psql.Expression - IsNew psql.Expression - Notes psql.Expression - OrganizationID psql.Expression - PropertyOwnerName psql.Expression - PropertyOwnerPhone psql.Expression - ResidentOwned psql.Expression - ResidentPhone psql.Expression - Version psql.Expression + tableAlias string + AddressCity psql.Expression + AddressPostalCode psql.Expression + AddressStreet psql.Expression + Committed psql.Expression + Condition psql.Expression + Created psql.Expression + CreatorID psql.Expression + CSVFile psql.Expression + Deleted psql.Expression + Geom psql.Expression + H3cell psql.Expression + ID psql.Expression + IsInDistrict psql.Expression + IsNew psql.Expression + Notes psql.Expression + OrganizationID psql.Expression + PropertyOwnerName psql.Expression + ResidentOwned psql.Expression + Version psql.Expression + PropertyOwnerPhoneE164 psql.Expression + ResidentPhoneE164 psql.Expression } func (c fileuploadPoolColumns) Alias() string { @@ -137,27 +139,27 @@ func (fileuploadPoolColumns) AliasedAs(alias string) fileuploadPoolColumns { // All values are optional, and do not have to be set // Generated columns are not included type FileuploadPoolSetter struct { - AddressCity omit.Val[string] `db:"address_city" ` - AddressPostalCode omit.Val[string] `db:"address_postal_code" ` - AddressStreet omit.Val[string] `db:"address_street" ` - Committed omit.Val[bool] `db:"committed" ` - Condition omit.Val[enums.FileuploadPoolconditiontype] `db:"condition" ` - Created omit.Val[time.Time] `db:"created" ` - CreatorID omit.Val[int32] `db:"creator_id" ` - CSVFile omit.Val[int32] `db:"csv_file" ` - Deleted omitnull.Val[time.Time] `db:"deleted" ` - Geom omitnull.Val[string] `db:"geom" ` - H3cell omitnull.Val[string] `db:"h3cell" ` - ID omit.Val[int32] `db:"id,pk" ` - IsInDistrict omit.Val[bool] `db:"is_in_district" ` - IsNew omit.Val[bool] `db:"is_new" ` - Notes omit.Val[string] `db:"notes" ` - OrganizationID omit.Val[int32] `db:"organization_id" ` - PropertyOwnerName omit.Val[string] `db:"property_owner_name" ` - PropertyOwnerPhone omitnull.Val[string] `db:"property_owner_phone" ` - ResidentOwned omitnull.Val[bool] `db:"resident_owned" ` - ResidentPhone omitnull.Val[string] `db:"resident_phone" ` - Version omit.Val[int32] `db:"version,pk" ` + AddressCity omit.Val[string] `db:"address_city" ` + AddressPostalCode omit.Val[string] `db:"address_postal_code" ` + AddressStreet omit.Val[string] `db:"address_street" ` + Committed omit.Val[bool] `db:"committed" ` + Condition omit.Val[enums.FileuploadPoolconditiontype] `db:"condition" ` + Created omit.Val[time.Time] `db:"created" ` + CreatorID omit.Val[int32] `db:"creator_id" ` + CSVFile omit.Val[int32] `db:"csv_file" ` + Deleted omitnull.Val[time.Time] `db:"deleted" ` + Geom omitnull.Val[string] `db:"geom" ` + H3cell omitnull.Val[string] `db:"h3cell" ` + ID omit.Val[int32] `db:"id,pk" ` + IsInDistrict omit.Val[bool] `db:"is_in_district" ` + IsNew omit.Val[bool] `db:"is_new" ` + Notes omit.Val[string] `db:"notes" ` + OrganizationID omit.Val[int32] `db:"organization_id" ` + PropertyOwnerName omit.Val[string] `db:"property_owner_name" ` + ResidentOwned omitnull.Val[bool] `db:"resident_owned" ` + Version omit.Val[int32] `db:"version,pk" ` + PropertyOwnerPhoneE164 omitnull.Val[string] `db:"property_owner_phone_e164" ` + ResidentPhoneE164 omitnull.Val[string] `db:"resident_phone_e164" ` } func (s FileuploadPoolSetter) SetColumns() []string { @@ -213,18 +215,18 @@ func (s FileuploadPoolSetter) SetColumns() []string { if s.PropertyOwnerName.IsValue() { vals = append(vals, "property_owner_name") } - if !s.PropertyOwnerPhone.IsUnset() { - vals = append(vals, "property_owner_phone") - } if !s.ResidentOwned.IsUnset() { vals = append(vals, "resident_owned") } - if !s.ResidentPhone.IsUnset() { - vals = append(vals, "resident_phone") - } if s.Version.IsValue() { vals = append(vals, "version") } + if !s.PropertyOwnerPhoneE164.IsUnset() { + vals = append(vals, "property_owner_phone_e164") + } + if !s.ResidentPhoneE164.IsUnset() { + vals = append(vals, "resident_phone_e164") + } return vals } @@ -280,18 +282,18 @@ func (s FileuploadPoolSetter) Overwrite(t *FileuploadPool) { if s.PropertyOwnerName.IsValue() { t.PropertyOwnerName = s.PropertyOwnerName.MustGet() } - if !s.PropertyOwnerPhone.IsUnset() { - t.PropertyOwnerPhone = s.PropertyOwnerPhone.MustGetNull() - } if !s.ResidentOwned.IsUnset() { t.ResidentOwned = s.ResidentOwned.MustGetNull() } - if !s.ResidentPhone.IsUnset() { - t.ResidentPhone = s.ResidentPhone.MustGetNull() - } if s.Version.IsValue() { t.Version = s.Version.MustGet() } + if !s.PropertyOwnerPhoneE164.IsUnset() { + t.PropertyOwnerPhoneE164 = s.PropertyOwnerPhoneE164.MustGetNull() + } + if !s.ResidentPhoneE164.IsUnset() { + t.ResidentPhoneE164 = s.ResidentPhoneE164.MustGetNull() + } } func (s *FileuploadPoolSetter) Apply(q *dialect.InsertQuery) { @@ -403,26 +405,26 @@ func (s *FileuploadPoolSetter) Apply(q *dialect.InsertQuery) { vals[16] = psql.Raw("DEFAULT") } - if !s.PropertyOwnerPhone.IsUnset() { - vals[17] = psql.Arg(s.PropertyOwnerPhone.MustGetNull()) + if !s.ResidentOwned.IsUnset() { + vals[17] = psql.Arg(s.ResidentOwned.MustGetNull()) } else { vals[17] = psql.Raw("DEFAULT") } - if !s.ResidentOwned.IsUnset() { - vals[18] = psql.Arg(s.ResidentOwned.MustGetNull()) + if s.Version.IsValue() { + vals[18] = psql.Arg(s.Version.MustGet()) } else { vals[18] = psql.Raw("DEFAULT") } - if !s.ResidentPhone.IsUnset() { - vals[19] = psql.Arg(s.ResidentPhone.MustGetNull()) + if !s.PropertyOwnerPhoneE164.IsUnset() { + vals[19] = psql.Arg(s.PropertyOwnerPhoneE164.MustGetNull()) } else { vals[19] = psql.Raw("DEFAULT") } - if s.Version.IsValue() { - vals[20] = psql.Arg(s.Version.MustGet()) + if !s.ResidentPhoneE164.IsUnset() { + vals[20] = psql.Arg(s.ResidentPhoneE164.MustGetNull()) } else { vals[20] = psql.Raw("DEFAULT") } @@ -557,13 +559,6 @@ func (s FileuploadPoolSetter) Expressions(prefix ...string) []bob.Expression { }}) } - if !s.PropertyOwnerPhone.IsUnset() { - exprs = append(exprs, expr.Join{Sep: " = ", Exprs: []bob.Expression{ - psql.Quote(append(prefix, "property_owner_phone")...), - psql.Arg(s.PropertyOwnerPhone), - }}) - } - if !s.ResidentOwned.IsUnset() { exprs = append(exprs, expr.Join{Sep: " = ", Exprs: []bob.Expression{ psql.Quote(append(prefix, "resident_owned")...), @@ -571,13 +566,6 @@ func (s FileuploadPoolSetter) Expressions(prefix ...string) []bob.Expression { }}) } - if !s.ResidentPhone.IsUnset() { - exprs = append(exprs, expr.Join{Sep: " = ", Exprs: []bob.Expression{ - psql.Quote(append(prefix, "resident_phone")...), - psql.Arg(s.ResidentPhone), - }}) - } - if s.Version.IsValue() { exprs = append(exprs, expr.Join{Sep: " = ", Exprs: []bob.Expression{ psql.Quote(append(prefix, "version")...), @@ -585,6 +573,20 @@ func (s FileuploadPoolSetter) Expressions(prefix ...string) []bob.Expression { }}) } + if !s.PropertyOwnerPhoneE164.IsUnset() { + exprs = append(exprs, expr.Join{Sep: " = ", Exprs: []bob.Expression{ + psql.Quote(append(prefix, "property_owner_phone_e164")...), + psql.Arg(s.PropertyOwnerPhoneE164), + }}) + } + + if !s.ResidentPhoneE164.IsUnset() { + exprs = append(exprs, expr.Join{Sep: " = ", Exprs: []bob.Expression{ + psql.Quote(append(prefix, "resident_phone_e164")...), + psql.Arg(s.ResidentPhoneE164), + }}) + } + return exprs } @@ -893,6 +895,54 @@ func (os FileuploadPoolSlice) Organization(mods ...bob.Mod[*dialect.SelectQuery] )...) } +// PropertyOwnerPhoneE164Phone starts a query for related objects on comms.phone +func (o *FileuploadPool) PropertyOwnerPhoneE164Phone(mods ...bob.Mod[*dialect.SelectQuery]) CommsPhonesQuery { + return CommsPhones.Query(append(mods, + sm.Where(CommsPhones.Columns.E164.EQ(psql.Arg(o.PropertyOwnerPhoneE164))), + )...) +} + +func (os FileuploadPoolSlice) PropertyOwnerPhoneE164Phone(mods ...bob.Mod[*dialect.SelectQuery]) CommsPhonesQuery { + pkPropertyOwnerPhoneE164 := make(pgtypes.Array[null.Val[string]], 0, len(os)) + for _, o := range os { + if o == nil { + continue + } + pkPropertyOwnerPhoneE164 = append(pkPropertyOwnerPhoneE164, o.PropertyOwnerPhoneE164) + } + PKArgExpr := psql.Select(sm.Columns( + psql.F("unnest", psql.Cast(psql.Arg(pkPropertyOwnerPhoneE164), "text[]")), + )) + + return CommsPhones.Query(append(mods, + sm.Where(psql.Group(CommsPhones.Columns.E164).OP("IN", PKArgExpr)), + )...) +} + +// ResidentPhoneE164Phone starts a query for related objects on comms.phone +func (o *FileuploadPool) ResidentPhoneE164Phone(mods ...bob.Mod[*dialect.SelectQuery]) CommsPhonesQuery { + return CommsPhones.Query(append(mods, + sm.Where(CommsPhones.Columns.E164.EQ(psql.Arg(o.ResidentPhoneE164))), + )...) +} + +func (os FileuploadPoolSlice) ResidentPhoneE164Phone(mods ...bob.Mod[*dialect.SelectQuery]) CommsPhonesQuery { + pkResidentPhoneE164 := make(pgtypes.Array[null.Val[string]], 0, len(os)) + for _, o := range os { + if o == nil { + continue + } + pkResidentPhoneE164 = append(pkResidentPhoneE164, o.ResidentPhoneE164) + } + PKArgExpr := psql.Select(sm.Columns( + psql.F("unnest", psql.Cast(psql.Arg(pkResidentPhoneE164), "text[]")), + )) + + return CommsPhones.Query(append(mods, + sm.Where(psql.Group(CommsPhones.Columns.E164).OP("IN", PKArgExpr)), + )...) +} + func attachFileuploadPoolCreatorUser0(ctx context.Context, exec bob.Executor, count int, fileuploadPool0 *FileuploadPool, user1 *User) (*FileuploadPool, error) { setter := &FileuploadPoolSetter{ CreatorID: omit.From(user1.ID), @@ -1037,28 +1087,124 @@ func (fileuploadPool0 *FileuploadPool) AttachOrganization(ctx context.Context, e return nil } +func attachFileuploadPoolPropertyOwnerPhoneE164Phone0(ctx context.Context, exec bob.Executor, count int, fileuploadPool0 *FileuploadPool, commsPhone1 *CommsPhone) (*FileuploadPool, error) { + setter := &FileuploadPoolSetter{ + PropertyOwnerPhoneE164: omitnull.From(commsPhone1.E164), + } + + err := fileuploadPool0.Update(ctx, exec, setter) + if err != nil { + return nil, fmt.Errorf("attachFileuploadPoolPropertyOwnerPhoneE164Phone0: %w", err) + } + + return fileuploadPool0, nil +} + +func (fileuploadPool0 *FileuploadPool) InsertPropertyOwnerPhoneE164Phone(ctx context.Context, exec bob.Executor, related *CommsPhoneSetter) error { + var err error + + commsPhone1, err := CommsPhones.Insert(related).One(ctx, exec) + if err != nil { + return fmt.Errorf("inserting related objects: %w", err) + } + + _, err = attachFileuploadPoolPropertyOwnerPhoneE164Phone0(ctx, exec, 1, fileuploadPool0, commsPhone1) + if err != nil { + return err + } + + fileuploadPool0.R.PropertyOwnerPhoneE164Phone = commsPhone1 + + commsPhone1.R.PropertyOwnerPhoneE164Pools = append(commsPhone1.R.PropertyOwnerPhoneE164Pools, fileuploadPool0) + + return nil +} + +func (fileuploadPool0 *FileuploadPool) AttachPropertyOwnerPhoneE164Phone(ctx context.Context, exec bob.Executor, commsPhone1 *CommsPhone) error { + var err error + + _, err = attachFileuploadPoolPropertyOwnerPhoneE164Phone0(ctx, exec, 1, fileuploadPool0, commsPhone1) + if err != nil { + return err + } + + fileuploadPool0.R.PropertyOwnerPhoneE164Phone = commsPhone1 + + commsPhone1.R.PropertyOwnerPhoneE164Pools = append(commsPhone1.R.PropertyOwnerPhoneE164Pools, fileuploadPool0) + + return nil +} + +func attachFileuploadPoolResidentPhoneE164Phone0(ctx context.Context, exec bob.Executor, count int, fileuploadPool0 *FileuploadPool, commsPhone1 *CommsPhone) (*FileuploadPool, error) { + setter := &FileuploadPoolSetter{ + ResidentPhoneE164: omitnull.From(commsPhone1.E164), + } + + err := fileuploadPool0.Update(ctx, exec, setter) + if err != nil { + return nil, fmt.Errorf("attachFileuploadPoolResidentPhoneE164Phone0: %w", err) + } + + return fileuploadPool0, nil +} + +func (fileuploadPool0 *FileuploadPool) InsertResidentPhoneE164Phone(ctx context.Context, exec bob.Executor, related *CommsPhoneSetter) error { + var err error + + commsPhone1, err := CommsPhones.Insert(related).One(ctx, exec) + if err != nil { + return fmt.Errorf("inserting related objects: %w", err) + } + + _, err = attachFileuploadPoolResidentPhoneE164Phone0(ctx, exec, 1, fileuploadPool0, commsPhone1) + if err != nil { + return err + } + + fileuploadPool0.R.ResidentPhoneE164Phone = commsPhone1 + + commsPhone1.R.ResidentPhoneE164Pools = append(commsPhone1.R.ResidentPhoneE164Pools, fileuploadPool0) + + return nil +} + +func (fileuploadPool0 *FileuploadPool) AttachResidentPhoneE164Phone(ctx context.Context, exec bob.Executor, commsPhone1 *CommsPhone) error { + var err error + + _, err = attachFileuploadPoolResidentPhoneE164Phone0(ctx, exec, 1, fileuploadPool0, commsPhone1) + if err != nil { + return err + } + + fileuploadPool0.R.ResidentPhoneE164Phone = commsPhone1 + + commsPhone1.R.ResidentPhoneE164Pools = append(commsPhone1.R.ResidentPhoneE164Pools, fileuploadPool0) + + return nil +} + type fileuploadPoolWhere[Q psql.Filterable] struct { - AddressCity psql.WhereMod[Q, string] - AddressPostalCode psql.WhereMod[Q, string] - AddressStreet psql.WhereMod[Q, string] - Committed psql.WhereMod[Q, bool] - Condition psql.WhereMod[Q, enums.FileuploadPoolconditiontype] - Created psql.WhereMod[Q, time.Time] - CreatorID psql.WhereMod[Q, int32] - CSVFile psql.WhereMod[Q, int32] - Deleted psql.WhereNullMod[Q, time.Time] - Geom psql.WhereNullMod[Q, string] - H3cell psql.WhereNullMod[Q, string] - ID psql.WhereMod[Q, int32] - IsInDistrict psql.WhereMod[Q, bool] - IsNew psql.WhereMod[Q, bool] - Notes psql.WhereMod[Q, string] - OrganizationID psql.WhereMod[Q, int32] - PropertyOwnerName psql.WhereMod[Q, string] - PropertyOwnerPhone psql.WhereNullMod[Q, string] - ResidentOwned psql.WhereNullMod[Q, bool] - ResidentPhone psql.WhereNullMod[Q, string] - Version psql.WhereMod[Q, int32] + AddressCity psql.WhereMod[Q, string] + AddressPostalCode psql.WhereMod[Q, string] + AddressStreet psql.WhereMod[Q, string] + Committed psql.WhereMod[Q, bool] + Condition psql.WhereMod[Q, enums.FileuploadPoolconditiontype] + Created psql.WhereMod[Q, time.Time] + CreatorID psql.WhereMod[Q, int32] + CSVFile psql.WhereMod[Q, int32] + Deleted psql.WhereNullMod[Q, time.Time] + Geom psql.WhereNullMod[Q, string] + H3cell psql.WhereNullMod[Q, string] + ID psql.WhereMod[Q, int32] + IsInDistrict psql.WhereMod[Q, bool] + IsNew psql.WhereMod[Q, bool] + Notes psql.WhereMod[Q, string] + OrganizationID psql.WhereMod[Q, int32] + PropertyOwnerName psql.WhereMod[Q, string] + ResidentOwned psql.WhereNullMod[Q, bool] + Version psql.WhereMod[Q, int32] + PropertyOwnerPhoneE164 psql.WhereNullMod[Q, string] + ResidentPhoneE164 psql.WhereNullMod[Q, string] } func (fileuploadPoolWhere[Q]) AliasedAs(alias string) fileuploadPoolWhere[Q] { @@ -1067,27 +1213,27 @@ func (fileuploadPoolWhere[Q]) AliasedAs(alias string) fileuploadPoolWhere[Q] { func buildFileuploadPoolWhere[Q psql.Filterable](cols fileuploadPoolColumns) fileuploadPoolWhere[Q] { return fileuploadPoolWhere[Q]{ - AddressCity: psql.Where[Q, string](cols.AddressCity), - AddressPostalCode: psql.Where[Q, string](cols.AddressPostalCode), - AddressStreet: psql.Where[Q, string](cols.AddressStreet), - Committed: psql.Where[Q, bool](cols.Committed), - Condition: psql.Where[Q, enums.FileuploadPoolconditiontype](cols.Condition), - Created: psql.Where[Q, time.Time](cols.Created), - CreatorID: psql.Where[Q, int32](cols.CreatorID), - CSVFile: psql.Where[Q, int32](cols.CSVFile), - Deleted: psql.WhereNull[Q, time.Time](cols.Deleted), - Geom: psql.WhereNull[Q, string](cols.Geom), - H3cell: psql.WhereNull[Q, string](cols.H3cell), - ID: psql.Where[Q, int32](cols.ID), - IsInDistrict: psql.Where[Q, bool](cols.IsInDistrict), - IsNew: psql.Where[Q, bool](cols.IsNew), - Notes: psql.Where[Q, string](cols.Notes), - OrganizationID: psql.Where[Q, int32](cols.OrganizationID), - PropertyOwnerName: psql.Where[Q, string](cols.PropertyOwnerName), - PropertyOwnerPhone: psql.WhereNull[Q, string](cols.PropertyOwnerPhone), - ResidentOwned: psql.WhereNull[Q, bool](cols.ResidentOwned), - ResidentPhone: psql.WhereNull[Q, string](cols.ResidentPhone), - Version: psql.Where[Q, int32](cols.Version), + AddressCity: psql.Where[Q, string](cols.AddressCity), + AddressPostalCode: psql.Where[Q, string](cols.AddressPostalCode), + AddressStreet: psql.Where[Q, string](cols.AddressStreet), + Committed: psql.Where[Q, bool](cols.Committed), + Condition: psql.Where[Q, enums.FileuploadPoolconditiontype](cols.Condition), + Created: psql.Where[Q, time.Time](cols.Created), + CreatorID: psql.Where[Q, int32](cols.CreatorID), + CSVFile: psql.Where[Q, int32](cols.CSVFile), + Deleted: psql.WhereNull[Q, time.Time](cols.Deleted), + Geom: psql.WhereNull[Q, string](cols.Geom), + H3cell: psql.WhereNull[Q, string](cols.H3cell), + ID: psql.Where[Q, int32](cols.ID), + IsInDistrict: psql.Where[Q, bool](cols.IsInDistrict), + IsNew: psql.Where[Q, bool](cols.IsNew), + Notes: psql.Where[Q, string](cols.Notes), + OrganizationID: psql.Where[Q, int32](cols.OrganizationID), + PropertyOwnerName: psql.Where[Q, string](cols.PropertyOwnerName), + ResidentOwned: psql.WhereNull[Q, bool](cols.ResidentOwned), + Version: psql.Where[Q, int32](cols.Version), + PropertyOwnerPhoneE164: psql.WhereNull[Q, string](cols.PropertyOwnerPhoneE164), + ResidentPhoneE164: psql.WhereNull[Q, string](cols.ResidentPhoneE164), } } @@ -1133,15 +1279,41 @@ func (o *FileuploadPool) Preload(name string, retrieved any) error { rel.R.Pools = FileuploadPoolSlice{o} } return nil + case "PropertyOwnerPhoneE164Phone": + rel, ok := retrieved.(*CommsPhone) + if !ok { + return fmt.Errorf("fileuploadPool cannot load %T as %q", retrieved, name) + } + + o.R.PropertyOwnerPhoneE164Phone = rel + + if rel != nil { + rel.R.PropertyOwnerPhoneE164Pools = FileuploadPoolSlice{o} + } + return nil + case "ResidentPhoneE164Phone": + rel, ok := retrieved.(*CommsPhone) + if !ok { + return fmt.Errorf("fileuploadPool cannot load %T as %q", retrieved, name) + } + + o.R.ResidentPhoneE164Phone = rel + + if rel != nil { + rel.R.ResidentPhoneE164Pools = FileuploadPoolSlice{o} + } + return nil default: return fmt.Errorf("fileuploadPool has no relationship %q", name) } } type fileuploadPoolPreloader struct { - CreatorUser func(...psql.PreloadOption) psql.Preloader - CSVFileCSV func(...psql.PreloadOption) psql.Preloader - Organization func(...psql.PreloadOption) psql.Preloader + CreatorUser func(...psql.PreloadOption) psql.Preloader + CSVFileCSV func(...psql.PreloadOption) psql.Preloader + Organization func(...psql.PreloadOption) psql.Preloader + PropertyOwnerPhoneE164Phone func(...psql.PreloadOption) psql.Preloader + ResidentPhoneE164Phone func(...psql.PreloadOption) psql.Preloader } func buildFileuploadPoolPreloader() fileuploadPoolPreloader { @@ -1185,13 +1357,41 @@ func buildFileuploadPoolPreloader() fileuploadPoolPreloader { }, }, Organizations.Columns.Names(), opts...) }, + PropertyOwnerPhoneE164Phone: func(opts ...psql.PreloadOption) psql.Preloader { + return psql.Preload[*CommsPhone, CommsPhoneSlice](psql.PreloadRel{ + Name: "PropertyOwnerPhoneE164Phone", + Sides: []psql.PreloadSide{ + { + From: FileuploadPools, + To: CommsPhones, + FromColumns: []string{"property_owner_phone_e164"}, + ToColumns: []string{"e164"}, + }, + }, + }, CommsPhones.Columns.Names(), opts...) + }, + ResidentPhoneE164Phone: func(opts ...psql.PreloadOption) psql.Preloader { + return psql.Preload[*CommsPhone, CommsPhoneSlice](psql.PreloadRel{ + Name: "ResidentPhoneE164Phone", + Sides: []psql.PreloadSide{ + { + From: FileuploadPools, + To: CommsPhones, + FromColumns: []string{"resident_phone_e164"}, + ToColumns: []string{"e164"}, + }, + }, + }, CommsPhones.Columns.Names(), opts...) + }, } } type fileuploadPoolThenLoader[Q orm.Loadable] struct { - CreatorUser func(...bob.Mod[*dialect.SelectQuery]) orm.Loader[Q] - CSVFileCSV func(...bob.Mod[*dialect.SelectQuery]) orm.Loader[Q] - Organization func(...bob.Mod[*dialect.SelectQuery]) orm.Loader[Q] + CreatorUser func(...bob.Mod[*dialect.SelectQuery]) orm.Loader[Q] + CSVFileCSV func(...bob.Mod[*dialect.SelectQuery]) orm.Loader[Q] + Organization func(...bob.Mod[*dialect.SelectQuery]) orm.Loader[Q] + PropertyOwnerPhoneE164Phone func(...bob.Mod[*dialect.SelectQuery]) orm.Loader[Q] + ResidentPhoneE164Phone func(...bob.Mod[*dialect.SelectQuery]) orm.Loader[Q] } func buildFileuploadPoolThenLoader[Q orm.Loadable]() fileuploadPoolThenLoader[Q] { @@ -1204,6 +1404,12 @@ func buildFileuploadPoolThenLoader[Q orm.Loadable]() fileuploadPoolThenLoader[Q] type OrganizationLoadInterface interface { LoadOrganization(context.Context, bob.Executor, ...bob.Mod[*dialect.SelectQuery]) error } + type PropertyOwnerPhoneE164PhoneLoadInterface interface { + LoadPropertyOwnerPhoneE164Phone(context.Context, bob.Executor, ...bob.Mod[*dialect.SelectQuery]) error + } + type ResidentPhoneE164PhoneLoadInterface interface { + LoadResidentPhoneE164Phone(context.Context, bob.Executor, ...bob.Mod[*dialect.SelectQuery]) error + } return fileuploadPoolThenLoader[Q]{ CreatorUser: thenLoadBuilder[Q]( @@ -1224,6 +1430,18 @@ func buildFileuploadPoolThenLoader[Q orm.Loadable]() fileuploadPoolThenLoader[Q] return retrieved.LoadOrganization(ctx, exec, mods...) }, ), + PropertyOwnerPhoneE164Phone: thenLoadBuilder[Q]( + "PropertyOwnerPhoneE164Phone", + func(ctx context.Context, exec bob.Executor, retrieved PropertyOwnerPhoneE164PhoneLoadInterface, mods ...bob.Mod[*dialect.SelectQuery]) error { + return retrieved.LoadPropertyOwnerPhoneE164Phone(ctx, exec, mods...) + }, + ), + ResidentPhoneE164Phone: thenLoadBuilder[Q]( + "ResidentPhoneE164Phone", + func(ctx context.Context, exec bob.Executor, retrieved ResidentPhoneE164PhoneLoadInterface, mods ...bob.Mod[*dialect.SelectQuery]) error { + return retrieved.LoadResidentPhoneE164Phone(ctx, exec, mods...) + }, + ), } } @@ -1383,11 +1601,123 @@ func (os FileuploadPoolSlice) LoadOrganization(ctx context.Context, exec bob.Exe return nil } +// LoadPropertyOwnerPhoneE164Phone loads the fileuploadPool's PropertyOwnerPhoneE164Phone into the .R struct +func (o *FileuploadPool) LoadPropertyOwnerPhoneE164Phone(ctx context.Context, exec bob.Executor, mods ...bob.Mod[*dialect.SelectQuery]) error { + if o == nil { + return nil + } + + // Reset the relationship + o.R.PropertyOwnerPhoneE164Phone = nil + + related, err := o.PropertyOwnerPhoneE164Phone(mods...).One(ctx, exec) + if err != nil { + return err + } + + related.R.PropertyOwnerPhoneE164Pools = FileuploadPoolSlice{o} + + o.R.PropertyOwnerPhoneE164Phone = related + return nil +} + +// LoadPropertyOwnerPhoneE164Phone loads the fileuploadPool's PropertyOwnerPhoneE164Phone into the .R struct +func (os FileuploadPoolSlice) LoadPropertyOwnerPhoneE164Phone(ctx context.Context, exec bob.Executor, mods ...bob.Mod[*dialect.SelectQuery]) error { + if len(os) == 0 { + return nil + } + + commsPhones, err := os.PropertyOwnerPhoneE164Phone(mods...).All(ctx, exec) + if err != nil { + return err + } + + for _, o := range os { + if o == nil { + continue + } + + for _, rel := range commsPhones { + if !o.PropertyOwnerPhoneE164.IsValue() { + continue + } + + if !(o.PropertyOwnerPhoneE164.IsValue() && o.PropertyOwnerPhoneE164.MustGet() == rel.E164) { + continue + } + + rel.R.PropertyOwnerPhoneE164Pools = append(rel.R.PropertyOwnerPhoneE164Pools, o) + + o.R.PropertyOwnerPhoneE164Phone = rel + break + } + } + + return nil +} + +// LoadResidentPhoneE164Phone loads the fileuploadPool's ResidentPhoneE164Phone into the .R struct +func (o *FileuploadPool) LoadResidentPhoneE164Phone(ctx context.Context, exec bob.Executor, mods ...bob.Mod[*dialect.SelectQuery]) error { + if o == nil { + return nil + } + + // Reset the relationship + o.R.ResidentPhoneE164Phone = nil + + related, err := o.ResidentPhoneE164Phone(mods...).One(ctx, exec) + if err != nil { + return err + } + + related.R.ResidentPhoneE164Pools = FileuploadPoolSlice{o} + + o.R.ResidentPhoneE164Phone = related + return nil +} + +// LoadResidentPhoneE164Phone loads the fileuploadPool's ResidentPhoneE164Phone into the .R struct +func (os FileuploadPoolSlice) LoadResidentPhoneE164Phone(ctx context.Context, exec bob.Executor, mods ...bob.Mod[*dialect.SelectQuery]) error { + if len(os) == 0 { + return nil + } + + commsPhones, err := os.ResidentPhoneE164Phone(mods...).All(ctx, exec) + if err != nil { + return err + } + + for _, o := range os { + if o == nil { + continue + } + + for _, rel := range commsPhones { + if !o.ResidentPhoneE164.IsValue() { + continue + } + + if !(o.ResidentPhoneE164.IsValue() && o.ResidentPhoneE164.MustGet() == rel.E164) { + continue + } + + rel.R.ResidentPhoneE164Pools = append(rel.R.ResidentPhoneE164Pools, o) + + o.R.ResidentPhoneE164Phone = rel + break + } + } + + return nil +} + type fileuploadPoolJoins[Q dialect.Joinable] struct { - typ string - CreatorUser modAs[Q, userColumns] - CSVFileCSV modAs[Q, fileuploadCSVColumns] - Organization modAs[Q, organizationColumns] + typ string + CreatorUser modAs[Q, userColumns] + CSVFileCSV modAs[Q, fileuploadCSVColumns] + Organization modAs[Q, organizationColumns] + PropertyOwnerPhoneE164Phone modAs[Q, commsPhoneColumns] + ResidentPhoneE164Phone modAs[Q, commsPhoneColumns] } func (j fileuploadPoolJoins[Q]) aliasedAs(alias string) fileuploadPoolJoins[Q] { @@ -1436,6 +1766,34 @@ func buildFileuploadPoolJoins[Q dialect.Joinable](cols fileuploadPoolColumns, ty )) } + return mods + }, + }, + PropertyOwnerPhoneE164Phone: modAs[Q, commsPhoneColumns]{ + c: CommsPhones.Columns, + f: func(to commsPhoneColumns) bob.Mod[Q] { + mods := make(mods.QueryMods[Q], 0, 1) + + { + mods = append(mods, dialect.Join[Q](typ, CommsPhones.Name().As(to.Alias())).On( + to.E164.EQ(cols.PropertyOwnerPhoneE164), + )) + } + + return mods + }, + }, + ResidentPhoneE164Phone: modAs[Q, commsPhoneColumns]{ + c: CommsPhones.Columns, + f: func(to commsPhoneColumns) bob.Mod[Q] { + mods := make(mods.QueryMods[Q], 0, 1) + + { + mods = append(mods, dialect.Join[Q](typ, CommsPhones.Name().As(to.Alias())).On( + to.E164.EQ(cols.ResidentPhoneE164), + )) + } + return mods }, }, diff --git a/platform/csv/pool.go b/platform/csv/pool.go index cf3267bf..219a6f20 100644 --- a/platform/csv/pool.go +++ b/platform/csv/pool.go @@ -97,6 +97,11 @@ func ProcessJob(ctx context.Context, file_id int32) error { row, err := reader.Read() if err != nil { if err == io.EOF { + file.Update(ctx, txn, &models.FileuploadFileSetter{ + Status: omit.From(enums.FileuploadFilestatustypeParsed), + }) + log.Info().Int32("file_id", file_id).Msg("Set file to parsed") + txn.Commit(ctx) return nil } return fmt.Errorf("Failed to read all CSV records for file %d: %w", file_id, err) @@ -115,15 +120,15 @@ func ProcessJob(ctx context.Context, file_id int32) error { Geom: omitnull.FromPtr[string](nil), H3cell: omitnull.FromPtr[string](nil), // ID - generated - IsInDistrict: omit.From(false), - IsNew: omit.From(false), - Notes: omit.From(""), - OrganizationID: omit.From(file.OrganizationID), - PropertyOwnerName: omit.From(""), - PropertyOwnerPhone: omitnull.FromPtr[string](nil), - ResidentOwned: omitnull.FromPtr[bool](nil), - ResidentPhone: omitnull.FromPtr[string](nil), - Version: omit.From(int32(0)), + IsInDistrict: omit.From(false), + IsNew: omit.From(false), + Notes: omit.From(""), + OrganizationID: omit.From(file.OrganizationID), + PropertyOwnerName: omit.From(""), + PropertyOwnerPhoneE164: omitnull.FromPtr[string](nil), + ResidentOwned: omitnull.FromPtr[bool](nil), + ResidentPhoneE164: omitnull.FromPtr[string](nil), + Version: omit.From(int32(0)), } for i, col := range row { hdr := headers[i] @@ -153,7 +158,7 @@ func ProcessJob(ctx context.Context, file_id int32) error { continue } text.EnsureInDB(ctx, txn, *phone) - setter.PropertyOwnerPhone = omitnull.From(text.PhoneString(*phone)) + setter.PropertyOwnerPhoneE164 = omitnull.From(text.PhoneString(*phone)) case headerResidentOwned: boolValue, err := parseBool(col) if err != nil { @@ -162,7 +167,13 @@ func ProcessJob(ctx context.Context, file_id int32) error { } setter.ResidentOwned = omitnull.From(boolValue) case headerResidentPhone: - setter.ResidentPhone = omitnull.From(col) + phone, err := text.ParsePhoneNumber(col) + if err != nil { + addError(ctx, txn, c, int32(row_number), int32(i), fmt.Sprintf("'%s' is not a phone number that we recognize. Ideally it should be of the form '+12223334444'", col)) + continue + } + text.EnsureInDB(ctx, txn, *phone) + setter.ResidentPhoneE164 = omitnull.From(text.PhoneString(*phone)) } } _, err = models.FileuploadPools.Insert(&setter).Exec(ctx, txn) @@ -171,11 +182,6 @@ func ProcessJob(ctx context.Context, file_id int32) error { } row_number = row_number + 1 } - file.Update(ctx, txn, &models.FileuploadFileSetter{ - Status: omit.From(enums.FileuploadFilestatustypeParsed), - }) - txn.Commit(ctx) - return nil } func addError(ctx context.Context, txn bob.Tx, c *models.FileuploadCSV, row_number int32, column_number int32, msg string) error { r, err := models.FileuploadErrorCSVS.Insert(&models.FileuploadErrorCSVSetter{ @@ -188,7 +194,7 @@ func addError(ctx context.Context, txn bob.Tx, c *models.FileuploadCSV, row_numb if err != nil { return fmt.Errorf("Failed to add error: %w", err) } - log.Info().Int32("id", r.ID).Int32("file_id", c.FileID).Str("msg", msg).Msg("Created CSV file error") + log.Info().Int32("id", r.ID).Int32("file_id", c.FileID).Str("msg", msg).Int32("row", row_number).Int32("col", column_number).Msg("Created CSV file error") return nil } func addImportError(file *models.FileuploadFile, err error) {