diff --git a/auth/content.go b/auth/content.go index ca17caf8..be54792e 100644 --- a/auth/content.go +++ b/auth/content.go @@ -17,7 +17,7 @@ func ContentForUser(ctx context.Context, user *models.User) (platform.User, erro org := user.R.Organization var organization platform.Organization if org != nil { - organization.ID = int(org.ID) + organization.ID = int32(org.ID) organization.Name = org.Name } return platform.User{ diff --git a/db/dberrors/lead.bob.go b/db/dberrors/lead.bob.go new file mode 100644 index 00000000..7a80f68c --- /dev/null +++ b/db/dberrors/lead.bob.go @@ -0,0 +1,17 @@ +// Code generated by BobGen psql v0.42.5. DO NOT EDIT. +// This file is meant to be re-generated in place and/or deleted at any time. + +package dberrors + +var LeadErrors = &leadErrors{ + ErrUniqueLeadPkey: &UniqueConstraintError{ + schema: "", + table: "lead", + columns: []string{"id"}, + s: "lead_pkey", + }, +} + +type leadErrors struct { + ErrUniqueLeadPkey *UniqueConstraintError +} diff --git a/db/dbinfo/compliance_report_request.bob.go b/db/dbinfo/compliance_report_request.bob.go index 4e13586d..07da12c9 100644 --- a/db/dbinfo/compliance_report_request.bob.go +++ b/db/dbinfo/compliance_report_request.bob.go @@ -51,21 +51,12 @@ var ComplianceReportRequests = Table[ Generated: false, AutoIncr: false, }, - SiteID: column{ - Name: "site_id", + LeadID: column{ + Name: "lead_id", DBType: "integer", - Default: "", + Default: "NULL", Comment: "", - Nullable: false, - Generated: false, - AutoIncr: false, - }, - SiteVersion: column{ - Name: "site_version", - DBType: "integer", - Default: "", - Comment: "", - Nullable: false, + Nullable: true, Generated: false, AutoIncr: false, }, @@ -121,14 +112,14 @@ var ComplianceReportRequests = Table[ ForeignTable: "user_", ForeignColumns: []string{"id"}, }, - ComplianceReportRequestComplianceReportRequestSiteIDSiteVersionFkey: foreignKey{ + ComplianceReportRequestComplianceReportRequestLeadIDFkey: foreignKey{ constraint: constraint{ - Name: "compliance_report_request.compliance_report_request_site_id_site_version_fkey", - Columns: []string{"site_id", "site_version"}, + Name: "compliance_report_request.compliance_report_request_lead_id_fkey", + Columns: []string{"lead_id"}, Comment: "", }, - ForeignTable: "site", - ForeignColumns: []string{"id", "version"}, + ForeignTable: "lead", + ForeignColumns: []string{"id"}, }, }, Uniques: complianceReportRequestUniques{ @@ -143,17 +134,16 @@ var ComplianceReportRequests = Table[ } type complianceReportRequestColumns struct { - Created column - Creator column - ID column - PublicID column - SiteID column - SiteVersion column + Created column + Creator column + ID column + PublicID column + LeadID column } func (c complianceReportRequestColumns) AsSlice() []column { return []column{ - c.Created, c.Creator, c.ID, c.PublicID, c.SiteID, c.SiteVersion, + c.Created, c.Creator, c.ID, c.PublicID, c.LeadID, } } @@ -169,13 +159,13 @@ func (i complianceReportRequestIndexes) AsSlice() []index { } type complianceReportRequestForeignKeys struct { - ComplianceReportRequestComplianceReportRequestCreatorFkey foreignKey - ComplianceReportRequestComplianceReportRequestSiteIDSiteVersionFkey foreignKey + ComplianceReportRequestComplianceReportRequestCreatorFkey foreignKey + ComplianceReportRequestComplianceReportRequestLeadIDFkey foreignKey } func (f complianceReportRequestForeignKeys) AsSlice() []foreignKey { return []foreignKey{ - f.ComplianceReportRequestComplianceReportRequestCreatorFkey, f.ComplianceReportRequestComplianceReportRequestSiteIDSiteVersionFkey, + f.ComplianceReportRequestComplianceReportRequestCreatorFkey, f.ComplianceReportRequestComplianceReportRequestLeadIDFkey, } } diff --git a/db/dbinfo/fileupload.file.bob.go b/db/dbinfo/fileupload.file.bob.go index fa94a8f6..a26e4e13 100644 --- a/db/dbinfo/fileupload.file.bob.go +++ b/db/dbinfo/fileupload.file.bob.go @@ -105,6 +105,15 @@ var FileuploadFiles = Table[ Generated: false, AutoIncr: false, }, + Committer: column{ + Name: "committer", + DBType: "integer", + Default: "NULL", + Comment: "", + Nullable: true, + Generated: false, + AutoIncr: false, + }, }, Indexes: fileuploadFileIndexes{ FilePkey: index{ @@ -131,6 +140,15 @@ var FileuploadFiles = Table[ Comment: "", }, ForeignKeys: fileuploadFileForeignKeys{ + FileuploadFileFileCommitterFkey: foreignKey{ + constraint: constraint{ + Name: "fileupload.file.file_committer_fkey", + Columns: []string{"committer"}, + Comment: "", + }, + ForeignTable: "user_", + ForeignColumns: []string{"id"}, + }, FileuploadFileFileCreatorIDFkey: foreignKey{ constraint: constraint{ Name: "fileupload.file.file_creator_id_fkey", @@ -165,11 +183,12 @@ type fileuploadFileColumns struct { Status column SizeBytes column FileUUID column + Committer column } func (c fileuploadFileColumns) AsSlice() []column { return []column{ - c.ID, c.ContentType, c.Created, c.CreatorID, c.Deleted, c.Name, c.OrganizationID, c.Status, c.SizeBytes, c.FileUUID, + c.ID, c.ContentType, c.Created, c.CreatorID, c.Deleted, c.Name, c.OrganizationID, c.Status, c.SizeBytes, c.FileUUID, c.Committer, } } @@ -184,13 +203,14 @@ func (i fileuploadFileIndexes) AsSlice() []index { } type fileuploadFileForeignKeys struct { + FileuploadFileFileCommitterFkey foreignKey FileuploadFileFileCreatorIDFkey foreignKey FileuploadFileFileOrganizationIDFkey foreignKey } func (f fileuploadFileForeignKeys) AsSlice() []foreignKey { return []foreignKey{ - f.FileuploadFileFileCreatorIDFkey, f.FileuploadFileFileOrganizationIDFkey, + f.FileuploadFileFileCommitterFkey, f.FileuploadFileFileCreatorIDFkey, f.FileuploadFileFileOrganizationIDFkey, } } diff --git a/db/dbinfo/fileupload.pool.bob.go b/db/dbinfo/fileupload.pool.bob.go index 3358ad67..55291872 100644 --- a/db/dbinfo/fileupload.pool.bob.go +++ b/db/dbinfo/fileupload.pool.bob.go @@ -42,15 +42,6 @@ var FileuploadPools = Table[ Generated: false, AutoIncr: false, }, - Condition: column{ - Name: "condition", - DBType: "fileupload.poolconditiontype", - Default: "", - Comment: "", - Nullable: false, - Generated: false, - AutoIncr: false, - }, Created: column{ Name: "created", DBType: "timestamp without time zone", @@ -222,6 +213,15 @@ var FileuploadPools = Table[ Generated: false, AutoIncr: false, }, + Condition: column{ + Name: "condition", + DBType: "public.poolconditiontype", + Default: "", + Comment: "", + Nullable: false, + Generated: false, + AutoIncr: false, + }, }, Indexes: fileuploadPoolIndexes{ PoolPkey: index{ @@ -293,7 +293,6 @@ type fileuploadPoolColumns struct { AddressPostalCode column AddressStreet column Committed column - Condition column Created column CreatorID column CSVFile column @@ -313,11 +312,12 @@ type fileuploadPoolColumns struct { AddressNumber column AddressLocality column AddressRegion column + Condition column } func (c fileuploadPoolColumns) AsSlice() []column { return []column{ - 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.PropertyOwnerName, c.PropertyOwnerPhoneE164, c.ResidentOwned, c.ResidentPhoneE164, c.LineNumber, c.Tags, c.AddressNumber, c.AddressLocality, c.AddressRegion, + c.AddressPostalCode, c.AddressStreet, c.Committed, c.Created, c.CreatorID, c.CSVFile, c.Deleted, c.Geom, c.H3cell, c.ID, c.IsInDistrict, c.IsNew, c.Notes, c.PropertyOwnerName, c.PropertyOwnerPhoneE164, c.ResidentOwned, c.ResidentPhoneE164, c.LineNumber, c.Tags, c.AddressNumber, c.AddressLocality, c.AddressRegion, c.Condition, } } diff --git a/db/dbinfo/lead.bob.go b/db/dbinfo/lead.bob.go new file mode 100644 index 00000000..79028940 --- /dev/null +++ b/db/dbinfo/lead.bob.go @@ -0,0 +1,187 @@ +// Code generated by BobGen psql v0.42.5. DO NOT EDIT. +// This file is meant to be re-generated in place and/or deleted at any time. + +package dbinfo + +import "github.com/aarondl/opt/null" + +var Leads = Table[ + leadColumns, + leadIndexes, + leadForeignKeys, + leadUniques, + leadChecks, +]{ + Schema: "", + Name: "lead", + Columns: leadColumns{ + Created: column{ + Name: "created", + DBType: "timestamp without time zone", + Default: "", + Comment: "", + Nullable: false, + Generated: false, + AutoIncr: false, + }, + Creator: column{ + Name: "creator", + DBType: "integer", + Default: "", + Comment: "", + Nullable: false, + Generated: false, + AutoIncr: false, + }, + ID: column{ + Name: "id", + DBType: "integer", + Default: "nextval('lead_id_seq'::regclass)", + Comment: "", + Nullable: false, + Generated: false, + AutoIncr: false, + }, + OrganizationID: column{ + Name: "organization_id", + DBType: "integer", + Default: "", + Comment: "", + Nullable: false, + Generated: false, + AutoIncr: false, + }, + SiteID: column{ + Name: "site_id", + DBType: "integer", + Default: "NULL", + Comment: "", + Nullable: true, + Generated: false, + AutoIncr: false, + }, + SiteVersion: column{ + Name: "site_version", + DBType: "integer", + Default: "NULL", + Comment: "", + Nullable: true, + Generated: false, + AutoIncr: false, + }, + Type: column{ + Name: "type_", + DBType: "public.leadtype", + Default: "", + Comment: "", + Nullable: false, + Generated: false, + AutoIncr: false, + }, + }, + Indexes: leadIndexes{ + LeadPkey: index{ + Type: "btree", + Name: "lead_pkey", + Columns: []indexColumn{ + { + Name: "id", + Desc: null.FromCond(false, true), + IsExpression: false, + }, + }, + Unique: true, + Comment: "", + NullsFirst: []bool{false}, + NullsDistinct: false, + Where: "", + Include: []string{}, + }, + }, + PrimaryKey: &constraint{ + Name: "lead_pkey", + Columns: []string{"id"}, + Comment: "", + }, + ForeignKeys: leadForeignKeys{ + LeadLeadCreatorFkey: foreignKey{ + constraint: constraint{ + Name: "lead.lead_creator_fkey", + Columns: []string{"creator"}, + Comment: "", + }, + ForeignTable: "user_", + ForeignColumns: []string{"id"}, + }, + LeadLeadOrganizationIDFkey: foreignKey{ + constraint: constraint{ + Name: "lead.lead_organization_id_fkey", + Columns: []string{"organization_id"}, + Comment: "", + }, + ForeignTable: "organization", + ForeignColumns: []string{"id"}, + }, + LeadLeadSiteIDSiteVersionFkey: foreignKey{ + constraint: constraint{ + Name: "lead.lead_site_id_site_version_fkey", + Columns: []string{"site_id", "site_version"}, + Comment: "", + }, + ForeignTable: "site", + ForeignColumns: []string{"id", "version"}, + }, + }, + + Comment: "", +} + +type leadColumns struct { + Created column + Creator column + ID column + OrganizationID column + SiteID column + SiteVersion column + Type column +} + +func (c leadColumns) AsSlice() []column { + return []column{ + c.Created, c.Creator, c.ID, c.OrganizationID, c.SiteID, c.SiteVersion, c.Type, + } +} + +type leadIndexes struct { + LeadPkey index +} + +func (i leadIndexes) AsSlice() []index { + return []index{ + i.LeadPkey, + } +} + +type leadForeignKeys struct { + LeadLeadCreatorFkey foreignKey + LeadLeadOrganizationIDFkey foreignKey + LeadLeadSiteIDSiteVersionFkey foreignKey +} + +func (f leadForeignKeys) AsSlice() []foreignKey { + return []foreignKey{ + f.LeadLeadCreatorFkey, f.LeadLeadOrganizationIDFkey, f.LeadLeadSiteIDSiteVersionFkey, + } +} + +type leadUniques struct{} + +func (u leadUniques) AsSlice() []constraint { + return []constraint{} +} + +type leadChecks struct{} + +func (c leadChecks) AsSlice() []check { + return []check{} +} diff --git a/db/enums/enums.bob.go b/db/enums/enums.bob.go index 0ae52a03..c68b4529 100644 --- a/db/enums/enums.bob.go +++ b/db/enums/enums.bob.go @@ -1074,91 +1074,6 @@ func (e *FileuploadFilestatustype) Scan(value any) error { return nil } -// Enum values for FileuploadPoolconditiontype -const ( - FileuploadPoolconditiontypeGreen FileuploadPoolconditiontype = "green" - FileuploadPoolconditiontypeMurky FileuploadPoolconditiontype = "murky" - FileuploadPoolconditiontypeBlue FileuploadPoolconditiontype = "blue" - FileuploadPoolconditiontypeDry FileuploadPoolconditiontype = "dry" - FileuploadPoolconditiontypeFalsePool FileuploadPoolconditiontype = "false pool" - FileuploadPoolconditiontypeUnknown FileuploadPoolconditiontype = "unknown" -) - -func AllFileuploadPoolconditiontype() []FileuploadPoolconditiontype { - return []FileuploadPoolconditiontype{ - FileuploadPoolconditiontypeGreen, - FileuploadPoolconditiontypeMurky, - FileuploadPoolconditiontypeBlue, - FileuploadPoolconditiontypeDry, - FileuploadPoolconditiontypeFalsePool, - FileuploadPoolconditiontypeUnknown, - } -} - -type FileuploadPoolconditiontype string - -func (e FileuploadPoolconditiontype) String() string { - return string(e) -} - -func (e FileuploadPoolconditiontype) Valid() bool { - switch e { - case FileuploadPoolconditiontypeGreen, - FileuploadPoolconditiontypeMurky, - FileuploadPoolconditiontypeBlue, - FileuploadPoolconditiontypeDry, - FileuploadPoolconditiontypeFalsePool, - FileuploadPoolconditiontypeUnknown: - return true - default: - return false - } -} - -// useful when testing in other packages -func (e FileuploadPoolconditiontype) All() []FileuploadPoolconditiontype { - return AllFileuploadPoolconditiontype() -} - -func (e FileuploadPoolconditiontype) MarshalText() ([]byte, error) { - return []byte(e), nil -} - -func (e *FileuploadPoolconditiontype) UnmarshalText(text []byte) error { - return e.Scan(text) -} - -func (e FileuploadPoolconditiontype) MarshalBinary() ([]byte, error) { - return []byte(e), nil -} - -func (e *FileuploadPoolconditiontype) UnmarshalBinary(data []byte) error { - return e.Scan(data) -} - -func (e FileuploadPoolconditiontype) Value() (driver.Value, error) { - return string(e), nil -} - -func (e *FileuploadPoolconditiontype) Scan(value any) error { - switch x := value.(type) { - case string: - *e = FileuploadPoolconditiontype(x) - case []byte: - *e = FileuploadPoolconditiontype(x) - case nil: - return fmt.Errorf("cannot nil into FileuploadPoolconditiontype") - default: - return fmt.Errorf("cannot scan type %T: %v", value, value) - } - - if !e.Valid() { - return fmt.Errorf("invalid FileuploadPoolconditiontype value: %s", *e) - } - - return nil -} - // Enum values for H3aggregationtype const ( H3aggregationtypeMosquitosource H3aggregationtype = "MosquitoSource" @@ -1377,8 +1292,79 @@ func (e *Imagedatatype) Scan(value any) error { return nil } +// Enum values for Leadtype +const ( + LeadtypeGreenPool Leadtype = "green-pool" +) + +func AllLeadtype() []Leadtype { + return []Leadtype{ + LeadtypeGreenPool, + } +} + +type Leadtype string + +func (e Leadtype) String() string { + return string(e) +} + +func (e Leadtype) Valid() bool { + switch e { + case LeadtypeGreenPool: + return true + default: + return false + } +} + +// useful when testing in other packages +func (e Leadtype) All() []Leadtype { + return AllLeadtype() +} + +func (e Leadtype) MarshalText() ([]byte, error) { + return []byte(e), nil +} + +func (e *Leadtype) UnmarshalText(text []byte) error { + return e.Scan(text) +} + +func (e Leadtype) MarshalBinary() ([]byte, error) { + return []byte(e), nil +} + +func (e *Leadtype) UnmarshalBinary(data []byte) error { + return e.Scan(data) +} + +func (e Leadtype) Value() (driver.Value, error) { + return string(e), nil +} + +func (e *Leadtype) Scan(value any) error { + switch x := value.(type) { + case string: + *e = Leadtype(x) + case []byte: + *e = Leadtype(x) + case nil: + return fmt.Errorf("cannot nil into Leadtype") + default: + return fmt.Errorf("cannot scan type %T: %v", value, value) + } + + if !e.Valid() { + return fmt.Errorf("invalid Leadtype value: %s", *e) + } + + return nil +} + // Enum values for Mosquitospecies const ( + MosquitospeciesNone Mosquitospecies = "none" MosquitospeciesAedesAegypti Mosquitospecies = "aedes aegypti" MosquitospeciesAedesAlbopictus Mosquitospecies = "aedes albopictus" MosquitospeciesCulexPipiens Mosquitospecies = "culex pipiens" @@ -1387,6 +1373,7 @@ const ( func AllMosquitospecies() []Mosquitospecies { return []Mosquitospecies{ + MosquitospeciesNone, MosquitospeciesAedesAegypti, MosquitospeciesAedesAlbopictus, MosquitospeciesCulexPipiens, @@ -1402,7 +1389,8 @@ func (e Mosquitospecies) String() string { func (e Mosquitospecies) Valid() bool { switch e { - case MosquitospeciesAedesAegypti, + case MosquitospeciesNone, + MosquitospeciesAedesAegypti, MosquitospeciesAedesAlbopictus, MosquitospeciesCulexPipiens, MosquitospeciesCulexTarsalis: @@ -1531,6 +1519,7 @@ const ( PoolconditiontypeBlue Poolconditiontype = "blue" PoolconditiontypeDry Poolconditiontype = "dry" PoolconditiontypeFalsePool Poolconditiontype = "false pool" + PoolconditiontypeUnknown Poolconditiontype = "unknown" PoolconditiontypeGreen Poolconditiontype = "green" PoolconditiontypeMurky Poolconditiontype = "murky" ) @@ -1540,6 +1529,7 @@ func AllPoolconditiontype() []Poolconditiontype { PoolconditiontypeBlue, PoolconditiontypeDry, PoolconditiontypeFalsePool, + PoolconditiontypeUnknown, PoolconditiontypeGreen, PoolconditiontypeMurky, } @@ -1556,6 +1546,7 @@ func (e Poolconditiontype) Valid() bool { case PoolconditiontypeBlue, PoolconditiontypeDry, PoolconditiontypeFalsePool, + PoolconditiontypeUnknown, PoolconditiontypeGreen, PoolconditiontypeMurky: return true @@ -1953,24 +1944,24 @@ func (e *PublicreportReportstatustype) Scan(value any) error { // Enum values for Signaltype const ( - SignaltypeFlyoverU2epool Signaltype = "flyover.pool" - SignaltypePlanU2efollowup Signaltype = "plan.followup" - SignaltypePublicreportU2ewater Signaltype = "publicreport.water" - SignaltypePublicreportU2enuisance Signaltype = "publicreport.nuisance" - SignaltypeResidualU2eexiring Signaltype = "residual.exiring" - SignaltypeSurveillanceU2eobservation Signaltype = "surveillance.observation" - SignaltypeTrapU2espike Signaltype = "trap.spike" + SignaltypeFlyoverPool Signaltype = "flyover pool" + SignaltypePlanFollowup Signaltype = "plan followup" + SignaltypePublicreportWater Signaltype = "publicreport water" + SignaltypePublicreportNuisance Signaltype = "publicreport nuisance" + SignaltypeResidualExiring Signaltype = "residual exiring" + SignaltypeSurveillanceObservation Signaltype = "surveillance observation" + SignaltypeTrapSpike Signaltype = "trap spike" ) func AllSignaltype() []Signaltype { return []Signaltype{ - SignaltypeFlyoverU2epool, - SignaltypePlanU2efollowup, - SignaltypePublicreportU2ewater, - SignaltypePublicreportU2enuisance, - SignaltypeResidualU2eexiring, - SignaltypeSurveillanceU2eobservation, - SignaltypeTrapU2espike, + SignaltypeFlyoverPool, + SignaltypePlanFollowup, + SignaltypePublicreportWater, + SignaltypePublicreportNuisance, + SignaltypeResidualExiring, + SignaltypeSurveillanceObservation, + SignaltypeTrapSpike, } } @@ -1982,13 +1973,13 @@ func (e Signaltype) String() string { func (e Signaltype) Valid() bool { switch e { - case SignaltypeFlyoverU2epool, - SignaltypePlanU2efollowup, - SignaltypePublicreportU2ewater, - SignaltypePublicreportU2enuisance, - SignaltypeResidualU2eexiring, - SignaltypeSurveillanceU2eobservation, - SignaltypeTrapU2espike: + case SignaltypeFlyoverPool, + SignaltypePlanFollowup, + SignaltypePublicreportWater, + SignaltypePublicreportNuisance, + SignaltypeResidualExiring, + SignaltypeSurveillanceObservation, + SignaltypeTrapSpike: return true default: return false diff --git a/db/factory/bobfactory_context.bob.go b/db/factory/bobfactory_context.bob.go index 8a650a24..eb21fbcb 100644 --- a/db/factory/bobfactory_context.bob.go +++ b/db/factory/bobfactory_context.bob.go @@ -114,7 +114,7 @@ var ( // Relationship Contexts for compliance_report_request complianceReportRequestWithParentsCascadingCtx = newContextual[bool]("complianceReportRequestWithParentsCascading") complianceReportRequestRelCreatorUserCtx = newContextual[bool]("compliance_report_request.user_.compliance_report_request.compliance_report_request_creator_fkey") - complianceReportRequestRelSiteCtx = newContextual[bool]("compliance_report_request.site.compliance_report_request.compliance_report_request_site_id_site_version_fkey") + complianceReportRequestRelLeadCtx = newContextual[bool]("compliance_report_request.lead.compliance_report_request.compliance_report_request_lead_id_fkey") complianceReportRequestRelMailersCtx = newContextual[bool]("comms.mailer.compliance_report_request.compliance_report_request_mailer.compliance_report_request_mai_compliance_report_request_id_fkeycompliance_report_request_mailer.compliance_report_request_mailer_mailer_id_fkey") // Relationship Contexts for compliance_report_request_mailer @@ -262,6 +262,7 @@ var ( fileuploadFileWithParentsCascadingCtx = newContextual[bool]("fileuploadFileWithParentsCascading") fileuploadFileRelCSVCtx = newContextual[bool]("fileupload.csv.fileupload.file.fileupload.csv.csv_file_id_fkey") fileuploadFileRelErrorFilesCtx = newContextual[bool]("fileupload.error_file.fileupload.file.fileupload.error_file.error_file_file_id_fkey") + fileuploadFileRelCommitterUserCtx = newContextual[bool]("fileupload.file.user_.fileupload.file.file_committer_fkey") fileuploadFileRelCreatorUserCtx = newContextual[bool]("fileupload.file.user_.fileupload.file.file_creator_id_fkey") fileuploadFileRelOrganizationCtx = newContextual[bool]("fileupload.file.organization.fileupload.file.file_organization_id_fkey") fileuploadFileRelSitesCtx = newContextual[bool]("fileupload.file.site.site.site_file_id_fkey") @@ -286,6 +287,13 @@ var ( h3AggregationWithParentsCascadingCtx = newContextual[bool]("h3AggregationWithParentsCascading") h3AggregationRelOrganizationCtx = newContextual[bool]("h3_aggregation.organization.h3_aggregation.h3_aggregation_organization_id_fkey") + // Relationship Contexts for lead + leadWithParentsCascadingCtx = newContextual[bool]("leadWithParentsCascading") + leadRelComplianceReportRequestsCtx = newContextual[bool]("compliance_report_request.lead.compliance_report_request.compliance_report_request_lead_id_fkey") + leadRelCreatorUserCtx = newContextual[bool]("lead.user_.lead.lead_creator_fkey") + leadRelOrganizationCtx = newContextual[bool]("lead.organization.lead.lead_organization_id_fkey") + leadRelSiteCtx = newContextual[bool]("lead.site.lead.lead_site_id_site_version_fkey") + // Relationship Contexts for note_audio noteAudioWithParentsCascadingCtx = newContextual[bool]("noteAudioWithParentsCascading") noteAudioRelCreatorUserCtx = newContextual[bool]("note_audio.user_.note_audio.note_audio_creator_id_fkey") @@ -359,6 +367,7 @@ var ( organizationRelFieldseekerSyncsCtx = newContextual[bool]("fieldseeker_sync.organization.fieldseeker_sync.fieldseeker_sync_organization_id_fkey") organizationRelFilesCtx = newContextual[bool]("fileupload.file.organization.fileupload.file.file_organization_id_fkey") organizationRelH3AggregationsCtx = newContextual[bool]("h3_aggregation.organization.h3_aggregation.h3_aggregation_organization_id_fkey") + organizationRelLeadsCtx = newContextual[bool]("lead.organization.lead.lead_organization_id_fkey") organizationRelNoteAudiosCtx = newContextual[bool]("note_audio.organization.note_audio.note_audio_organization_id_fkey") organizationRelNoteImagesCtx = newContextual[bool]("note_image.organization.note_image.note_image_organization_id_fkey") organizationRelArcgisAccountAccountCtx = newContextual[bool]("arcgis.account.organization.organization.organization_arcgis_account_id_fkey") @@ -484,14 +493,14 @@ var ( signalPoolRelSignalCtx = newContextual[bool]("signal.signal_pool.signal_pool.signal_pool_signal_id_fkey") // Relationship Contexts for site - siteWithParentsCascadingCtx = newContextual[bool]("siteWithParentsCascading") - siteRelComplianceReportRequestsCtx = newContextual[bool]("compliance_report_request.site.compliance_report_request.compliance_report_request_site_id_site_version_fkey") - siteRelPoolsCtx = newContextual[bool]("pool.site.pool.pool_site_id_site_version_fkey") - siteRelResidentsCtx = newContextual[bool]("resident.site.resident.resident_site_id_site_version_fkey") - siteRelAddressCtx = newContextual[bool]("address.site.site.site_address_id_fkey") - siteRelCreatorUserCtx = newContextual[bool]("site.user_.site.site_creator_id_fkey") - siteRelFileCtx = newContextual[bool]("fileupload.file.site.site.site_file_id_fkey") - siteRelParcelCtx = newContextual[bool]("parcel.site.site.site_parcel_id_fkey") + siteWithParentsCascadingCtx = newContextual[bool]("siteWithParentsCascading") + siteRelLeadsCtx = newContextual[bool]("lead.site.lead.lead_site_id_site_version_fkey") + siteRelPoolsCtx = newContextual[bool]("pool.site.pool.pool_site_id_site_version_fkey") + siteRelResidentsCtx = newContextual[bool]("resident.site.resident.resident_site_id_site_version_fkey") + siteRelAddressCtx = newContextual[bool]("address.site.site.site_address_id_fkey") + siteRelCreatorUserCtx = newContextual[bool]("site.user_.site.site_creator_id_fkey") + siteRelFileCtx = newContextual[bool]("fileupload.file.site.site.site_file_id_fkey") + siteRelParcelCtx = newContextual[bool]("parcel.site.site.site_parcel_id_fkey") // Relationship Contexts for spatial_ref_sys spatialRefSyWithParentsCascadingCtx = newContextual[bool]("spatialRefSyWithParentsCascading") @@ -501,8 +510,10 @@ var ( userRelUserOauthTokensCtx = newContextual[bool]("arcgis.oauth_token.user_.arcgis.oauth_token.oauth_token_user_id_fkey") userRelPublicUserUserCtx = newContextual[bool]("arcgis.user_.user_.arcgis.user_.user__public_user_id_fkey") userRelCreatorComplianceReportRequestsCtx = newContextual[bool]("compliance_report_request.user_.compliance_report_request.compliance_report_request_creator_fkey") + userRelCommitterFilesCtx = newContextual[bool]("fileupload.file.user_.fileupload.file.file_committer_fkey") userRelCreatorFilesCtx = newContextual[bool]("fileupload.file.user_.fileupload.file.file_creator_id_fkey") userRelFileuploadPoolCtx = newContextual[bool]("fileupload.pool.user_.fileupload.pool.pool_creator_id_fkey") + userRelCreatorLeadsCtx = newContextual[bool]("lead.user_.lead.lead_creator_fkey") userRelCreatorNoteAudiosCtx = newContextual[bool]("note_audio.user_.note_audio.note_audio_creator_id_fkey") userRelDeletorNoteAudiosCtx = newContextual[bool]("note_audio.user_.note_audio.note_audio_deletor_id_fkey") userRelCreatorNoteImagesCtx = newContextual[bool]("note_image.user_.note_image.note_image_creator_id_fkey") diff --git a/db/factory/bobfactory_main.bob.go b/db/factory/bobfactory_main.bob.go index e4dde2cc..1fcca391 100644 --- a/db/factory/bobfactory_main.bob.go +++ b/db/factory/bobfactory_main.bob.go @@ -78,6 +78,7 @@ type Factory struct { baseGeometryColumnMods GeometryColumnModSlice baseGooseDBVersionMods GooseDBVersionModSlice baseH3AggregationMods H3AggregationModSlice + baseLeadMods LeadModSlice baseNoteAudioMods NoteAudioModSlice baseNoteAudioBreadcrumbMods NoteAudioBreadcrumbModSlice baseNoteAudioDatumMods NoteAudioDatumModSlice @@ -860,15 +861,14 @@ func (f *Factory) FromExistingComplianceReportRequest(m *models.ComplianceReport o.Creator = func() int32 { return m.Creator } o.ID = func() int32 { return m.ID } o.PublicID = func() string { return m.PublicID } - o.SiteID = func() int32 { return m.SiteID } - o.SiteVersion = func() int32 { return m.SiteVersion } + o.LeadID = func() null.Val[int32] { return m.LeadID } ctx := context.Background() if m.R.CreatorUser != nil { ComplianceReportRequestMods.WithExistingCreatorUser(m.R.CreatorUser).Apply(ctx, o) } - if m.R.Site != nil { - ComplianceReportRequestMods.WithExistingSite(m.R.Site).Apply(ctx, o) + if m.R.Lead != nil { + ComplianceReportRequestMods.WithExistingLead(m.R.Lead).Apply(ctx, o) } if len(m.R.Mailers) > 0 { ComplianceReportRequestMods.AddExistingMailers(m.R.Mailers...).Apply(ctx, o) @@ -2859,6 +2859,7 @@ func (f *Factory) FromExistingFileuploadFile(m *models.FileuploadFile) *Fileuplo o.Status = func() enums.FileuploadFilestatustype { return m.Status } o.SizeBytes = func() int32 { return m.SizeBytes } o.FileUUID = func() uuid.UUID { return m.FileUUID } + o.Committer = func() null.Val[int32] { return m.Committer } ctx := context.Background() if m.R.CSV != nil { @@ -2867,6 +2868,9 @@ func (f *Factory) FromExistingFileuploadFile(m *models.FileuploadFile) *Fileuplo if len(m.R.ErrorFiles) > 0 { FileuploadFileMods.AddExistingErrorFiles(m.R.ErrorFiles...).Apply(ctx, o) } + if m.R.CommitterUser != nil { + FileuploadFileMods.WithExistingCommitterUser(m.R.CommitterUser).Apply(ctx, o) + } if m.R.CreatorUser != nil { FileuploadFileMods.WithExistingCreatorUser(m.R.CreatorUser).Apply(ctx, o) } @@ -2902,7 +2906,6 @@ func (f *Factory) FromExistingFileuploadPool(m *models.FileuploadPool) *Fileuplo o.AddressPostalCode = func() string { return m.AddressPostalCode } o.AddressStreet = func() string { return m.AddressStreet } o.Committed = func() bool { return m.Committed } - o.Condition = func() enums.FileuploadPoolconditiontype { return m.Condition } o.Created = func() time.Time { return m.Created } o.CreatorID = func() int32 { return m.CreatorID } o.CSVFile = func() int32 { return m.CSVFile } @@ -2922,6 +2925,7 @@ func (f *Factory) FromExistingFileuploadPool(m *models.FileuploadPool) *Fileuplo o.AddressNumber = func() string { return m.AddressNumber } o.AddressLocality = func() string { return m.AddressLocality } o.AddressRegion = func() string { return m.AddressRegion } + o.Condition = func() enums.Poolconditiontype { return m.Condition } ctx := context.Background() if m.R.CreatorUser != nil { @@ -3062,6 +3066,50 @@ func (f *Factory) FromExistingH3Aggregation(m *models.H3Aggregation) *H3Aggregat return o } +func (f *Factory) NewLead(mods ...LeadMod) *LeadTemplate { + return f.NewLeadWithContext(context.Background(), mods...) +} + +func (f *Factory) NewLeadWithContext(ctx context.Context, mods ...LeadMod) *LeadTemplate { + o := &LeadTemplate{f: f} + + if f != nil { + f.baseLeadMods.Apply(ctx, o) + } + + LeadModSlice(mods).Apply(ctx, o) + + return o +} + +func (f *Factory) FromExistingLead(m *models.Lead) *LeadTemplate { + o := &LeadTemplate{f: f, alreadyPersisted: true} + + o.Created = func() time.Time { return m.Created } + o.Creator = func() int32 { return m.Creator } + o.ID = func() int32 { return m.ID } + o.OrganizationID = func() int32 { return m.OrganizationID } + o.SiteID = func() null.Val[int32] { return m.SiteID } + o.SiteVersion = func() null.Val[int32] { return m.SiteVersion } + o.Type = func() enums.Leadtype { return m.Type } + + ctx := context.Background() + if len(m.R.ComplianceReportRequests) > 0 { + LeadMods.AddExistingComplianceReportRequests(m.R.ComplianceReportRequests...).Apply(ctx, o) + } + if m.R.CreatorUser != nil { + LeadMods.WithExistingCreatorUser(m.R.CreatorUser).Apply(ctx, o) + } + if m.R.Organization != nil { + LeadMods.WithExistingOrganization(m.R.Organization).Apply(ctx, o) + } + if m.R.Site != nil { + LeadMods.WithExistingSite(m.R.Site).Apply(ctx, o) + } + + return o +} + func (f *Factory) NewNoteAudio(mods ...NoteAudioMod) *NoteAudioTemplate { return f.NewNoteAudioWithContext(context.Background(), mods...) } @@ -3484,6 +3532,9 @@ func (f *Factory) FromExistingOrganization(m *models.Organization) *Organization if len(m.R.H3Aggregations) > 0 { OrganizationMods.AddExistingH3Aggregations(m.R.H3Aggregations...).Apply(ctx, o) } + if len(m.R.Leads) > 0 { + OrganizationMods.AddExistingLeads(m.R.Leads...).Apply(ctx, o) + } if len(m.R.NoteAudios) > 0 { OrganizationMods.AddExistingNoteAudios(m.R.NoteAudios...).Apply(ctx, o) } @@ -4438,8 +4489,8 @@ func (f *Factory) FromExistingSite(m *models.Site) *SiteTemplate { o.Version = func() int32 { return m.Version } ctx := context.Background() - if len(m.R.ComplianceReportRequests) > 0 { - SiteMods.AddExistingComplianceReportRequests(m.R.ComplianceReportRequests...).Apply(ctx, o) + if len(m.R.Leads) > 0 { + SiteMods.AddExistingLeads(m.R.Leads...).Apply(ctx, o) } if len(m.R.Pools) > 0 { SiteMods.AddExistingPools(m.R.Pools...).Apply(ctx, o) @@ -4534,12 +4585,18 @@ func (f *Factory) FromExistingUser(m *models.User) *UserTemplate { if len(m.R.CreatorComplianceReportRequests) > 0 { UserMods.AddExistingCreatorComplianceReportRequests(m.R.CreatorComplianceReportRequests...).Apply(ctx, o) } + if len(m.R.CommitterFiles) > 0 { + UserMods.AddExistingCommitterFiles(m.R.CommitterFiles...).Apply(ctx, o) + } if len(m.R.CreatorFiles) > 0 { UserMods.AddExistingCreatorFiles(m.R.CreatorFiles...).Apply(ctx, o) } if len(m.R.FileuploadPool) > 0 { UserMods.AddExistingFileuploadPool(m.R.FileuploadPool...).Apply(ctx, o) } + if len(m.R.CreatorLeads) > 0 { + UserMods.AddExistingCreatorLeads(m.R.CreatorLeads...).Apply(ctx, o) + } if len(m.R.CreatorNoteAudios) > 0 { UserMods.AddExistingCreatorNoteAudios(m.R.CreatorNoteAudios...).Apply(ctx, o) } @@ -5049,6 +5106,14 @@ func (f *Factory) AddBaseH3AggregationMod(mods ...H3AggregationMod) { f.baseH3AggregationMods = append(f.baseH3AggregationMods, mods...) } +func (f *Factory) ClearBaseLeadMods() { + f.baseLeadMods = nil +} + +func (f *Factory) AddBaseLeadMod(mods ...LeadMod) { + f.baseLeadMods = append(f.baseLeadMods, mods...) +} + func (f *Factory) ClearBaseNoteAudioMods() { f.baseNoteAudioMods = nil } diff --git a/db/factory/bobfactory_random.bob.go b/db/factory/bobfactory_random.bob.go index 5e240e29..11f9ae33 100644 --- a/db/factory/bobfactory_random.bob.go +++ b/db/factory/bobfactory_random.bob.go @@ -201,16 +201,6 @@ func random_enums_FileuploadFilestatustype(f *faker.Faker, limits ...string) enu return all[f.IntBetween(0, len(all)-1)] } -func random_enums_FileuploadPoolconditiontype(f *faker.Faker, limits ...string) enums.FileuploadPoolconditiontype { - if f == nil { - f = &defaultFaker - } - - var e enums.FileuploadPoolconditiontype - all := e.All() - return all[f.IntBetween(0, len(all)-1)] -} - func random_enums_H3aggregationtype(f *faker.Faker, limits ...string) enums.H3aggregationtype { if f == nil { f = &defaultFaker @@ -231,6 +221,16 @@ func random_enums_Hashtype(f *faker.Faker, limits ...string) enums.Hashtype { return all[f.IntBetween(0, len(all)-1)] } +func random_enums_Leadtype(f *faker.Faker, limits ...string) enums.Leadtype { + if f == nil { + f = &defaultFaker + } + + var e enums.Leadtype + all := e.All() + return all[f.IntBetween(0, len(all)-1)] +} + func random_enums_Mosquitospecies(f *faker.Faker, limits ...string) enums.Mosquitospecies { if f == nil { f = &defaultFaker diff --git a/db/factory/compliance_report_request.bob.go b/db/factory/compliance_report_request.bob.go index 9d62156b..135ca877 100644 --- a/db/factory/compliance_report_request.bob.go +++ b/db/factory/compliance_report_request.bob.go @@ -10,7 +10,9 @@ import ( "github.com/Gleipnir-Technology/bob" models "github.com/Gleipnir-Technology/nidus-sync/db/models" + "github.com/aarondl/opt/null" "github.com/aarondl/opt/omit" + "github.com/aarondl/opt/omitnull" "github.com/jaswdr/faker/v2" ) @@ -35,12 +37,11 @@ func (mods ComplianceReportRequestModSlice) Apply(ctx context.Context, n *Compli // ComplianceReportRequestTemplate is an object representing the database table. // all columns are optional and should be set by mods type ComplianceReportRequestTemplate struct { - Created func() time.Time - Creator func() int32 - ID func() int32 - PublicID func() string - SiteID func() int32 - SiteVersion func() int32 + Created func() time.Time + Creator func() int32 + ID func() int32 + PublicID func() string + LeadID func() null.Val[int32] r complianceReportRequestR f *Factory @@ -50,15 +51,15 @@ type ComplianceReportRequestTemplate struct { type complianceReportRequestR struct { CreatorUser *complianceReportRequestRCreatorUserR - Site *complianceReportRequestRSiteR + Lead *complianceReportRequestRLeadR Mailers []*complianceReportRequestRMailersR } type complianceReportRequestRCreatorUserR struct { o *UserTemplate } -type complianceReportRequestRSiteR struct { - o *SiteTemplate +type complianceReportRequestRLeadR struct { + o *LeadTemplate } type complianceReportRequestRMailersR struct { number int @@ -82,12 +83,11 @@ func (t ComplianceReportRequestTemplate) setModelRels(o *models.ComplianceReport o.R.CreatorUser = rel } - if t.r.Site != nil { - rel := t.r.Site.o.Build() + if t.r.Lead != nil { + rel := t.r.Lead.o.Build() rel.R.ComplianceReportRequests = append(rel.R.ComplianceReportRequests, o) - o.SiteID = rel.ID // h2 - o.SiteVersion = rel.Version // h2 - o.R.Site = rel + o.LeadID = null.From(rel.ID) // h2 + o.R.Lead = rel } if t.r.Mailers != nil { @@ -124,13 +124,9 @@ func (o ComplianceReportRequestTemplate) BuildSetter() *models.ComplianceReportR val := o.PublicID() m.PublicID = omit.From(val) } - if o.SiteID != nil { - val := o.SiteID() - m.SiteID = omit.From(val) - } - if o.SiteVersion != nil { - val := o.SiteVersion() - m.SiteVersion = omit.From(val) + if o.LeadID != nil { + val := o.LeadID() + m.LeadID = omitnull.FromNull(val) } return m @@ -166,11 +162,8 @@ func (o ComplianceReportRequestTemplate) Build() *models.ComplianceReportRequest if o.PublicID != nil { m.PublicID = o.PublicID() } - if o.SiteID != nil { - m.SiteID = o.SiteID() - } - if o.SiteVersion != nil { - m.SiteVersion = o.SiteVersion() + if o.LeadID != nil { + m.LeadID = o.LeadID() } o.setModelRels(m) @@ -204,14 +197,6 @@ func ensureCreatableComplianceReportRequest(m *models.ComplianceReportRequestSet val := random_string(nil) m.PublicID = omit.From(val) } - if !(m.SiteID.IsValue()) { - val := random_int32(nil) - m.SiteID = omit.From(val) - } - if !(m.SiteVersion.IsValue()) { - val := random_int32(nil) - m.SiteVersion = omit.From(val) - } } // insertOptRels creates and inserts any optional the relationships on *models.ComplianceReportRequest @@ -220,6 +205,25 @@ func ensureCreatableComplianceReportRequest(m *models.ComplianceReportRequestSet func (o *ComplianceReportRequestTemplate) insertOptRels(ctx context.Context, exec bob.Executor, m *models.ComplianceReportRequest) error { var err error + isLeadDone, _ := complianceReportRequestRelLeadCtx.Value(ctx) + if !isLeadDone && o.r.Lead != nil { + ctx = complianceReportRequestRelLeadCtx.WithValue(ctx, true) + if o.r.Lead.o.alreadyPersisted { + m.R.Lead = o.r.Lead.o.Build() + } else { + var rel1 *models.Lead + rel1, err = o.r.Lead.o.Create(ctx, exec) + if err != nil { + return err + } + err = m.AttachLead(ctx, exec, rel1) + if err != nil { + return err + } + } + + } + return err } @@ -247,31 +251,12 @@ func (o *ComplianceReportRequestTemplate) Create(ctx context.Context, exec bob.E opt.Creator = omit.From(rel0.ID) - if o.r.Site == nil { - ComplianceReportRequestMods.WithNewSite().Apply(ctx, o) - } - - var rel1 *models.Site - - if o.r.Site.o.alreadyPersisted { - rel1 = o.r.Site.o.Build() - } else { - rel1, err = o.r.Site.o.Create(ctx, exec) - if err != nil { - return nil, err - } - } - - opt.SiteID = omit.From(rel1.ID) - opt.SiteVersion = omit.From(rel1.Version) - m, err := models.ComplianceReportRequests.Insert(opt).One(ctx, exec) if err != nil { return nil, err } m.R.CreatorUser = rel0 - m.R.Site = rel1 if err := o.insertOptRels(ctx, exec, m); err != nil { return nil, err @@ -354,8 +339,7 @@ func (m complianceReportRequestMods) RandomizeAllColumns(f *faker.Faker) Complia ComplianceReportRequestMods.RandomCreator(f), ComplianceReportRequestMods.RandomID(f), ComplianceReportRequestMods.RandomPublicID(f), - ComplianceReportRequestMods.RandomSiteID(f), - ComplianceReportRequestMods.RandomSiteVersion(f), + ComplianceReportRequestMods.RandomLeadID(f), } } @@ -484,63 +468,54 @@ func (m complianceReportRequestMods) RandomPublicID(f *faker.Faker) ComplianceRe } // Set the model columns to this value -func (m complianceReportRequestMods) SiteID(val int32) ComplianceReportRequestMod { +func (m complianceReportRequestMods) LeadID(val null.Val[int32]) ComplianceReportRequestMod { return ComplianceReportRequestModFunc(func(_ context.Context, o *ComplianceReportRequestTemplate) { - o.SiteID = func() int32 { return val } + o.LeadID = func() null.Val[int32] { return val } }) } // Set the Column from the function -func (m complianceReportRequestMods) SiteIDFunc(f func() int32) ComplianceReportRequestMod { +func (m complianceReportRequestMods) LeadIDFunc(f func() null.Val[int32]) ComplianceReportRequestMod { return ComplianceReportRequestModFunc(func(_ context.Context, o *ComplianceReportRequestTemplate) { - o.SiteID = f + o.LeadID = f }) } // Clear any values for the column -func (m complianceReportRequestMods) UnsetSiteID() ComplianceReportRequestMod { +func (m complianceReportRequestMods) UnsetLeadID() ComplianceReportRequestMod { return ComplianceReportRequestModFunc(func(_ context.Context, o *ComplianceReportRequestTemplate) { - o.SiteID = nil + o.LeadID = nil }) } // Generates a random value for the column using the given faker // if faker is nil, a default faker is used -func (m complianceReportRequestMods) RandomSiteID(f *faker.Faker) ComplianceReportRequestMod { +// The generated value is sometimes null +func (m complianceReportRequestMods) RandomLeadID(f *faker.Faker) ComplianceReportRequestMod { return ComplianceReportRequestModFunc(func(_ context.Context, o *ComplianceReportRequestTemplate) { - o.SiteID = func() int32 { - return random_int32(f) + o.LeadID = func() null.Val[int32] { + if f == nil { + f = &defaultFaker + } + + val := random_int32(f) + return null.From(val) } }) } -// Set the model columns to this value -func (m complianceReportRequestMods) SiteVersion(val int32) ComplianceReportRequestMod { - return ComplianceReportRequestModFunc(func(_ context.Context, o *ComplianceReportRequestTemplate) { - o.SiteVersion = func() int32 { return val } - }) -} - -// Set the Column from the function -func (m complianceReportRequestMods) SiteVersionFunc(f func() int32) ComplianceReportRequestMod { - return ComplianceReportRequestModFunc(func(_ context.Context, o *ComplianceReportRequestTemplate) { - o.SiteVersion = f - }) -} - -// Clear any values for the column -func (m complianceReportRequestMods) UnsetSiteVersion() ComplianceReportRequestMod { - return ComplianceReportRequestModFunc(func(_ context.Context, o *ComplianceReportRequestTemplate) { - o.SiteVersion = nil - }) -} - // Generates a random value for the column using the given faker // if faker is nil, a default faker is used -func (m complianceReportRequestMods) RandomSiteVersion(f *faker.Faker) ComplianceReportRequestMod { +// The generated value is never null +func (m complianceReportRequestMods) RandomLeadIDNotNull(f *faker.Faker) ComplianceReportRequestMod { return ComplianceReportRequestModFunc(func(_ context.Context, o *ComplianceReportRequestTemplate) { - o.SiteVersion = func() int32 { - return random_int32(f) + o.LeadID = func() null.Val[int32] { + if f == nil { + f = &defaultFaker + } + + val := random_int32(f) + return null.From(val) } }) } @@ -558,8 +533,8 @@ func (m complianceReportRequestMods) WithParentsCascading() ComplianceReportRequ } { - related := o.f.NewSiteWithContext(ctx, SiteMods.WithParentsCascading()) - m.WithSite(related).Apply(ctx, o) + related := o.f.NewLeadWithContext(ctx, LeadMods.WithParentsCascading()) + m.WithLead(related).Apply(ctx, o) } }) } @@ -594,33 +569,33 @@ func (m complianceReportRequestMods) WithoutCreatorUser() ComplianceReportReques }) } -func (m complianceReportRequestMods) WithSite(rel *SiteTemplate) ComplianceReportRequestMod { +func (m complianceReportRequestMods) WithLead(rel *LeadTemplate) ComplianceReportRequestMod { return ComplianceReportRequestModFunc(func(ctx context.Context, o *ComplianceReportRequestTemplate) { - o.r.Site = &complianceReportRequestRSiteR{ + o.r.Lead = &complianceReportRequestRLeadR{ o: rel, } }) } -func (m complianceReportRequestMods) WithNewSite(mods ...SiteMod) ComplianceReportRequestMod { +func (m complianceReportRequestMods) WithNewLead(mods ...LeadMod) ComplianceReportRequestMod { return ComplianceReportRequestModFunc(func(ctx context.Context, o *ComplianceReportRequestTemplate) { - related := o.f.NewSiteWithContext(ctx, mods...) + related := o.f.NewLeadWithContext(ctx, mods...) - m.WithSite(related).Apply(ctx, o) + m.WithLead(related).Apply(ctx, o) }) } -func (m complianceReportRequestMods) WithExistingSite(em *models.Site) ComplianceReportRequestMod { +func (m complianceReportRequestMods) WithExistingLead(em *models.Lead) ComplianceReportRequestMod { return ComplianceReportRequestModFunc(func(ctx context.Context, o *ComplianceReportRequestTemplate) { - o.r.Site = &complianceReportRequestRSiteR{ - o: o.f.FromExistingSite(em), + o.r.Lead = &complianceReportRequestRLeadR{ + o: o.f.FromExistingLead(em), } }) } -func (m complianceReportRequestMods) WithoutSite() ComplianceReportRequestMod { +func (m complianceReportRequestMods) WithoutLead() ComplianceReportRequestMod { return ComplianceReportRequestModFunc(func(ctx context.Context, o *ComplianceReportRequestTemplate) { - o.r.Site = nil + o.r.Lead = nil }) } diff --git a/db/factory/fileupload.file.bob.go b/db/factory/fileupload.file.bob.go index e0950498..066b6540 100644 --- a/db/factory/fileupload.file.bob.go +++ b/db/factory/fileupload.file.bob.go @@ -49,6 +49,7 @@ type FileuploadFileTemplate struct { Status func() enums.FileuploadFilestatustype SizeBytes func() int32 FileUUID func() uuid.UUID + Committer func() null.Val[int32] r fileuploadFileR f *Factory @@ -57,11 +58,12 @@ type FileuploadFileTemplate struct { } type fileuploadFileR struct { - CSV *fileuploadFileRCSVR - ErrorFiles []*fileuploadFileRErrorFilesR - CreatorUser *fileuploadFileRCreatorUserR - Organization *fileuploadFileROrganizationR - Sites []*fileuploadFileRSitesR + CSV *fileuploadFileRCSVR + ErrorFiles []*fileuploadFileRErrorFilesR + CommitterUser *fileuploadFileRCommitterUserR + CreatorUser *fileuploadFileRCreatorUserR + Organization *fileuploadFileROrganizationR + Sites []*fileuploadFileRSitesR } type fileuploadFileRCSVR struct { @@ -71,6 +73,9 @@ type fileuploadFileRErrorFilesR struct { number int o *FileuploadErrorFileTemplate } +type fileuploadFileRCommitterUserR struct { + o *UserTemplate +} type fileuploadFileRCreatorUserR struct { o *UserTemplate } @@ -112,6 +117,13 @@ func (t FileuploadFileTemplate) setModelRels(o *models.FileuploadFile) { o.R.ErrorFiles = rel } + if t.r.CommitterUser != nil { + rel := t.r.CommitterUser.o.Build() + rel.R.CommitterFiles = append(rel.R.CommitterFiles, o) + o.Committer = null.From(rel.ID) // h2 + o.R.CommitterUser = rel + } + if t.r.CreatorUser != nil { rel := t.r.CreatorUser.o.Build() rel.R.CreatorFiles = append(rel.R.CreatorFiles, o) @@ -185,6 +197,10 @@ func (o FileuploadFileTemplate) BuildSetter() *models.FileuploadFileSetter { val := o.FileUUID() m.FileUUID = omit.From(val) } + if o.Committer != nil { + val := o.Committer() + m.Committer = omitnull.FromNull(val) + } return m } @@ -237,6 +253,9 @@ func (o FileuploadFileTemplate) Build() *models.FileuploadFile { if o.FileUUID != nil { m.FileUUID = o.FileUUID() } + if o.Committer != nil { + m.Committer = o.Committer() + } o.setModelRels(m) @@ -336,6 +355,25 @@ func (o *FileuploadFileTemplate) insertOptRels(ctx context.Context, exec bob.Exe } } + isCommitterUserDone, _ := fileuploadFileRelCommitterUserCtx.Value(ctx) + if !isCommitterUserDone && o.r.CommitterUser != nil { + ctx = fileuploadFileRelCommitterUserCtx.WithValue(ctx, true) + if o.r.CommitterUser.o.alreadyPersisted { + m.R.CommitterUser = o.r.CommitterUser.o.Build() + } else { + var rel2 *models.User + rel2, err = o.r.CommitterUser.o.Create(ctx, exec) + if err != nil { + return err + } + err = m.AttachCommitterUser(ctx, exec, rel2) + if err != nil { + return err + } + } + + } + isSitesDone, _ := fileuploadFileRelSitesCtx.Value(ctx) if !isSitesDone && o.r.Sites != nil { ctx = fileuploadFileRelSitesCtx.WithValue(ctx, true) @@ -343,12 +381,12 @@ func (o *FileuploadFileTemplate) insertOptRels(ctx context.Context, exec bob.Exe if r.o.alreadyPersisted { m.R.Sites = append(m.R.Sites, r.o.Build()) } else { - rel4, err := r.o.CreateMany(ctx, exec, r.number) + rel5, err := r.o.CreateMany(ctx, exec, r.number) if err != nil { return err } - err = m.AttachSites(ctx, exec, rel4...) + err = m.AttachSites(ctx, exec, rel5...) if err != nil { return err } @@ -370,43 +408,43 @@ func (o *FileuploadFileTemplate) Create(ctx context.Context, exec bob.Executor) FileuploadFileMods.WithNewCreatorUser().Apply(ctx, o) } - var rel2 *models.User + var rel3 *models.User if o.r.CreatorUser.o.alreadyPersisted { - rel2 = o.r.CreatorUser.o.Build() + rel3 = o.r.CreatorUser.o.Build() } else { - rel2, err = o.r.CreatorUser.o.Create(ctx, exec) + rel3, err = o.r.CreatorUser.o.Create(ctx, exec) if err != nil { return nil, err } } - opt.CreatorID = omit.From(rel2.ID) + opt.CreatorID = omit.From(rel3.ID) if o.r.Organization == nil { FileuploadFileMods.WithNewOrganization().Apply(ctx, o) } - var rel3 *models.Organization + var rel4 *models.Organization if o.r.Organization.o.alreadyPersisted { - rel3 = o.r.Organization.o.Build() + rel4 = o.r.Organization.o.Build() } else { - rel3, err = o.r.Organization.o.Create(ctx, exec) + rel4, err = o.r.Organization.o.Create(ctx, exec) if err != nil { return nil, err } } - opt.OrganizationID = omit.From(rel3.ID) + opt.OrganizationID = omit.From(rel4.ID) m, err := models.FileuploadFiles.Insert(opt).One(ctx, exec) if err != nil { return nil, err } - m.R.CreatorUser = rel2 - m.R.Organization = rel3 + m.R.CreatorUser = rel3 + m.R.Organization = rel4 if err := o.insertOptRels(ctx, exec, m); err != nil { return nil, err @@ -495,6 +533,7 @@ func (m fileuploadFileMods) RandomizeAllColumns(f *faker.Faker) FileuploadFileMo FileuploadFileMods.RandomStatus(f), FileuploadFileMods.RandomSizeBytes(f), FileuploadFileMods.RandomFileUUID(f), + FileuploadFileMods.RandomCommitter(f), } } @@ -830,6 +869,59 @@ func (m fileuploadFileMods) RandomFileUUID(f *faker.Faker) FileuploadFileMod { }) } +// Set the model columns to this value +func (m fileuploadFileMods) Committer(val null.Val[int32]) FileuploadFileMod { + return FileuploadFileModFunc(func(_ context.Context, o *FileuploadFileTemplate) { + o.Committer = func() null.Val[int32] { return val } + }) +} + +// Set the Column from the function +func (m fileuploadFileMods) CommitterFunc(f func() null.Val[int32]) FileuploadFileMod { + return FileuploadFileModFunc(func(_ context.Context, o *FileuploadFileTemplate) { + o.Committer = f + }) +} + +// Clear any values for the column +func (m fileuploadFileMods) UnsetCommitter() FileuploadFileMod { + return FileuploadFileModFunc(func(_ context.Context, o *FileuploadFileTemplate) { + o.Committer = 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 fileuploadFileMods) RandomCommitter(f *faker.Faker) FileuploadFileMod { + return FileuploadFileModFunc(func(_ context.Context, o *FileuploadFileTemplate) { + o.Committer = func() null.Val[int32] { + if f == nil { + f = &defaultFaker + } + + val := random_int32(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 fileuploadFileMods) RandomCommitterNotNull(f *faker.Faker) FileuploadFileMod { + return FileuploadFileModFunc(func(_ context.Context, o *FileuploadFileTemplate) { + o.Committer = func() null.Val[int32] { + if f == nil { + f = &defaultFaker + } + + val := random_int32(f) + return null.From(val) + } + }) +} + func (m fileuploadFileMods) WithParentsCascading() FileuploadFileMod { return FileuploadFileModFunc(func(ctx context.Context, o *FileuploadFileTemplate) { if isDone, _ := fileuploadFileWithParentsCascadingCtx.Value(ctx); isDone { @@ -841,6 +933,11 @@ func (m fileuploadFileMods) WithParentsCascading() FileuploadFileMod { related := o.f.NewFileuploadCSVWithContext(ctx, FileuploadCSVMods.WithParentsCascading()) m.WithCSV(related).Apply(ctx, o) } + { + + related := o.f.NewUserWithContext(ctx, UserMods.WithParentsCascading()) + m.WithCommitterUser(related).Apply(ctx, o) + } { related := o.f.NewUserWithContext(ctx, UserMods.WithParentsCascading()) @@ -884,6 +981,36 @@ func (m fileuploadFileMods) WithoutCSV() FileuploadFileMod { }) } +func (m fileuploadFileMods) WithCommitterUser(rel *UserTemplate) FileuploadFileMod { + return FileuploadFileModFunc(func(ctx context.Context, o *FileuploadFileTemplate) { + o.r.CommitterUser = &fileuploadFileRCommitterUserR{ + o: rel, + } + }) +} + +func (m fileuploadFileMods) WithNewCommitterUser(mods ...UserMod) FileuploadFileMod { + return FileuploadFileModFunc(func(ctx context.Context, o *FileuploadFileTemplate) { + related := o.f.NewUserWithContext(ctx, mods...) + + m.WithCommitterUser(related).Apply(ctx, o) + }) +} + +func (m fileuploadFileMods) WithExistingCommitterUser(em *models.User) FileuploadFileMod { + return FileuploadFileModFunc(func(ctx context.Context, o *FileuploadFileTemplate) { + o.r.CommitterUser = &fileuploadFileRCommitterUserR{ + o: o.f.FromExistingUser(em), + } + }) +} + +func (m fileuploadFileMods) WithoutCommitterUser() FileuploadFileMod { + return FileuploadFileModFunc(func(ctx context.Context, o *FileuploadFileTemplate) { + o.r.CommitterUser = nil + }) +} + func (m fileuploadFileMods) WithCreatorUser(rel *UserTemplate) FileuploadFileMod { return FileuploadFileModFunc(func(ctx context.Context, o *FileuploadFileTemplate) { o.r.CreatorUser = &fileuploadFileRCreatorUserR{ diff --git a/db/factory/fileupload.pool.bob.go b/db/factory/fileupload.pool.bob.go index 4c0c56e4..c4d18d57 100644 --- a/db/factory/fileupload.pool.bob.go +++ b/db/factory/fileupload.pool.bob.go @@ -42,7 +42,6 @@ type FileuploadPoolTemplate struct { AddressPostalCode func() string AddressStreet func() string Committed func() bool - Condition func() enums.FileuploadPoolconditiontype Created func() time.Time CreatorID func() int32 CSVFile func() int32 @@ -62,6 +61,7 @@ type FileuploadPoolTemplate struct { AddressNumber func() string AddressLocality func() string AddressRegion func() string + Condition func() enums.Poolconditiontype r fileuploadPoolR f *Factory @@ -145,10 +145,6 @@ func (o FileuploadPoolTemplate) BuildSetter() *models.FileuploadPoolSetter { val := o.Committed() m.Committed = omit.From(val) } - if o.Condition != nil { - val := o.Condition() - m.Condition = omit.From(val) - } if o.Created != nil { val := o.Created() m.Created = omit.From(val) @@ -225,6 +221,10 @@ func (o FileuploadPoolTemplate) BuildSetter() *models.FileuploadPoolSetter { val := o.AddressRegion() m.AddressRegion = omit.From(val) } + if o.Condition != nil { + val := o.Condition() + m.Condition = omit.From(val) + } return m } @@ -256,9 +256,6 @@ func (o FileuploadPoolTemplate) Build() *models.FileuploadPool { if o.Committed != nil { m.Committed = o.Committed() } - if o.Condition != nil { - m.Condition = o.Condition() - } if o.Created != nil { m.Created = o.Created() } @@ -316,6 +313,9 @@ func (o FileuploadPoolTemplate) Build() *models.FileuploadPool { if o.AddressRegion != nil { m.AddressRegion = o.AddressRegion() } + if o.Condition != nil { + m.Condition = o.Condition() + } o.setModelRels(m) @@ -348,10 +348,6 @@ func ensureCreatableFileuploadPool(m *models.FileuploadPoolSetter) { val := random_bool(nil) m.Committed = omit.From(val) } - if !(m.Condition.IsValue()) { - val := random_enums_FileuploadPoolconditiontype(nil) - m.Condition = omit.From(val) - } if !(m.Created.IsValue()) { val := random_time_Time(nil) m.Created = omit.From(val) @@ -400,6 +396,10 @@ func ensureCreatableFileuploadPool(m *models.FileuploadPoolSetter) { val := random_string(nil) m.AddressRegion = omit.From(val) } + if !(m.Condition.IsValue()) { + val := random_enums_Poolconditiontype(nil) + m.Condition = omit.From(val) + } } // insertOptRels creates and inserts any optional the relationships on *models.FileuploadPool @@ -578,7 +578,6 @@ func (m fileuploadPoolMods) RandomizeAllColumns(f *faker.Faker) FileuploadPoolMo FileuploadPoolMods.RandomAddressPostalCode(f), FileuploadPoolMods.RandomAddressStreet(f), FileuploadPoolMods.RandomCommitted(f), - FileuploadPoolMods.RandomCondition(f), FileuploadPoolMods.RandomCreated(f), FileuploadPoolMods.RandomCreatorID(f), FileuploadPoolMods.RandomCSVFile(f), @@ -598,6 +597,7 @@ func (m fileuploadPoolMods) RandomizeAllColumns(f *faker.Faker) FileuploadPoolMo FileuploadPoolMods.RandomAddressNumber(f), FileuploadPoolMods.RandomAddressLocality(f), FileuploadPoolMods.RandomAddressRegion(f), + FileuploadPoolMods.RandomCondition(f), } } @@ -694,37 +694,6 @@ func (m fileuploadPoolMods) RandomCommitted(f *faker.Faker) FileuploadPoolMod { }) } -// Set the model columns to this value -func (m fileuploadPoolMods) Condition(val enums.FileuploadPoolconditiontype) FileuploadPoolMod { - return FileuploadPoolModFunc(func(_ context.Context, o *FileuploadPoolTemplate) { - o.Condition = func() enums.FileuploadPoolconditiontype { return val } - }) -} - -// Set the Column from the function -func (m fileuploadPoolMods) ConditionFunc(f func() enums.FileuploadPoolconditiontype) FileuploadPoolMod { - return FileuploadPoolModFunc(func(_ context.Context, o *FileuploadPoolTemplate) { - o.Condition = f - }) -} - -// Clear any values for the column -func (m fileuploadPoolMods) UnsetCondition() FileuploadPoolMod { - return FileuploadPoolModFunc(func(_ context.Context, o *FileuploadPoolTemplate) { - o.Condition = nil - }) -} - -// Generates a random value for the column using the given faker -// if faker is nil, a default faker is used -func (m fileuploadPoolMods) RandomCondition(f *faker.Faker) FileuploadPoolMod { - return FileuploadPoolModFunc(func(_ context.Context, o *FileuploadPoolTemplate) { - o.Condition = func() enums.FileuploadPoolconditiontype { - return random_enums_FileuploadPoolconditiontype(f) - } - }) -} - // Set the model columns to this value func (m fileuploadPoolMods) Created(val time.Time) FileuploadPoolMod { return FileuploadPoolModFunc(func(_ context.Context, o *FileuploadPoolTemplate) { @@ -1446,6 +1415,37 @@ func (m fileuploadPoolMods) RandomAddressRegion(f *faker.Faker) FileuploadPoolMo }) } +// Set the model columns to this value +func (m fileuploadPoolMods) Condition(val enums.Poolconditiontype) FileuploadPoolMod { + return FileuploadPoolModFunc(func(_ context.Context, o *FileuploadPoolTemplate) { + o.Condition = func() enums.Poolconditiontype { return val } + }) +} + +// Set the Column from the function +func (m fileuploadPoolMods) ConditionFunc(f func() enums.Poolconditiontype) FileuploadPoolMod { + return FileuploadPoolModFunc(func(_ context.Context, o *FileuploadPoolTemplate) { + o.Condition = f + }) +} + +// Clear any values for the column +func (m fileuploadPoolMods) UnsetCondition() FileuploadPoolMod { + return FileuploadPoolModFunc(func(_ context.Context, o *FileuploadPoolTemplate) { + o.Condition = nil + }) +} + +// Generates a random value for the column using the given faker +// if faker is nil, a default faker is used +func (m fileuploadPoolMods) RandomCondition(f *faker.Faker) FileuploadPoolMod { + return FileuploadPoolModFunc(func(_ context.Context, o *FileuploadPoolTemplate) { + o.Condition = func() enums.Poolconditiontype { + return random_enums_Poolconditiontype(f) + } + }) +} + func (m fileuploadPoolMods) WithParentsCascading() FileuploadPoolMod { return FileuploadPoolModFunc(func(ctx context.Context, o *FileuploadPoolTemplate) { if isDone, _ := fileuploadPoolWithParentsCascadingCtx.Value(ctx); isDone { diff --git a/db/factory/lead.bob.go b/db/factory/lead.bob.go new file mode 100644 index 00000000..79877f9b --- /dev/null +++ b/db/factory/lead.bob.go @@ -0,0 +1,841 @@ +// Code generated by BobGen psql v0.42.5. DO NOT EDIT. +// This file is meant to be re-generated in place and/or deleted at any time. + +package factory + +import ( + "context" + "testing" + "time" + + "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/aarondl/opt/omitnull" + "github.com/jaswdr/faker/v2" +) + +type LeadMod interface { + Apply(context.Context, *LeadTemplate) +} + +type LeadModFunc func(context.Context, *LeadTemplate) + +func (f LeadModFunc) Apply(ctx context.Context, n *LeadTemplate) { + f(ctx, n) +} + +type LeadModSlice []LeadMod + +func (mods LeadModSlice) Apply(ctx context.Context, n *LeadTemplate) { + for _, f := range mods { + f.Apply(ctx, n) + } +} + +// LeadTemplate is an object representing the database table. +// all columns are optional and should be set by mods +type LeadTemplate struct { + Created func() time.Time + Creator func() int32 + ID func() int32 + OrganizationID func() int32 + SiteID func() null.Val[int32] + SiteVersion func() null.Val[int32] + Type func() enums.Leadtype + + r leadR + f *Factory + + alreadyPersisted bool +} + +type leadR struct { + ComplianceReportRequests []*leadRComplianceReportRequestsR + CreatorUser *leadRCreatorUserR + Organization *leadROrganizationR + Site *leadRSiteR +} + +type leadRComplianceReportRequestsR struct { + number int + o *ComplianceReportRequestTemplate +} +type leadRCreatorUserR struct { + o *UserTemplate +} +type leadROrganizationR struct { + o *OrganizationTemplate +} +type leadRSiteR struct { + o *SiteTemplate +} + +// Apply mods to the LeadTemplate +func (o *LeadTemplate) Apply(ctx context.Context, mods ...LeadMod) { + for _, mod := range mods { + mod.Apply(ctx, o) + } +} + +// setModelRels creates and sets the relationships on *models.Lead +// according to the relationships in the template. Nothing is inserted into the db +func (t LeadTemplate) setModelRels(o *models.Lead) { + if t.r.ComplianceReportRequests != nil { + rel := models.ComplianceReportRequestSlice{} + for _, r := range t.r.ComplianceReportRequests { + related := r.o.BuildMany(r.number) + for _, rel := range related { + rel.LeadID = null.From(o.ID) // h2 + rel.R.Lead = o + } + rel = append(rel, related...) + } + o.R.ComplianceReportRequests = rel + } + + if t.r.CreatorUser != nil { + rel := t.r.CreatorUser.o.Build() + rel.R.CreatorLeads = append(rel.R.CreatorLeads, o) + o.Creator = rel.ID // h2 + o.R.CreatorUser = rel + } + + if t.r.Organization != nil { + rel := t.r.Organization.o.Build() + rel.R.Leads = append(rel.R.Leads, o) + o.OrganizationID = rel.ID // h2 + o.R.Organization = rel + } + + if t.r.Site != nil { + rel := t.r.Site.o.Build() + rel.R.Leads = append(rel.R.Leads, o) + o.SiteID = null.From(rel.ID) // h2 + o.SiteVersion = null.From(rel.Version) // h2 + o.R.Site = rel + } +} + +// BuildSetter returns an *models.LeadSetter +// this does nothing with the relationship templates +func (o LeadTemplate) BuildSetter() *models.LeadSetter { + m := &models.LeadSetter{} + + if o.Created != nil { + val := o.Created() + m.Created = omit.From(val) + } + if o.Creator != nil { + val := o.Creator() + m.Creator = omit.From(val) + } + if o.ID != nil { + val := o.ID() + m.ID = omit.From(val) + } + if o.OrganizationID != nil { + val := o.OrganizationID() + m.OrganizationID = omit.From(val) + } + if o.SiteID != nil { + val := o.SiteID() + m.SiteID = omitnull.FromNull(val) + } + if o.SiteVersion != nil { + val := o.SiteVersion() + m.SiteVersion = omitnull.FromNull(val) + } + if o.Type != nil { + val := o.Type() + m.Type = omit.From(val) + } + + return m +} + +// BuildManySetter returns an []*models.LeadSetter +// this does nothing with the relationship templates +func (o LeadTemplate) BuildManySetter(number int) []*models.LeadSetter { + m := make([]*models.LeadSetter, number) + + for i := range m { + m[i] = o.BuildSetter() + } + + return m +} + +// Build returns an *models.Lead +// Related objects are also created and placed in the .R field +// NOTE: Objects are not inserted into the database. Use LeadTemplate.Create +func (o LeadTemplate) Build() *models.Lead { + m := &models.Lead{} + + if o.Created != nil { + m.Created = o.Created() + } + if o.Creator != nil { + m.Creator = o.Creator() + } + if o.ID != nil { + m.ID = o.ID() + } + if o.OrganizationID != nil { + m.OrganizationID = o.OrganizationID() + } + if o.SiteID != nil { + m.SiteID = o.SiteID() + } + if o.SiteVersion != nil { + m.SiteVersion = o.SiteVersion() + } + if o.Type != nil { + m.Type = o.Type() + } + + o.setModelRels(m) + + return m +} + +// BuildMany returns an models.LeadSlice +// Related objects are also created and placed in the .R field +// NOTE: Objects are not inserted into the database. Use LeadTemplate.CreateMany +func (o LeadTemplate) BuildMany(number int) models.LeadSlice { + m := make(models.LeadSlice, number) + + for i := range m { + m[i] = o.Build() + } + + return m +} + +func ensureCreatableLead(m *models.LeadSetter) { + if !(m.Created.IsValue()) { + val := random_time_Time(nil) + m.Created = omit.From(val) + } + if !(m.Creator.IsValue()) { + val := random_int32(nil) + m.Creator = omit.From(val) + } + if !(m.OrganizationID.IsValue()) { + val := random_int32(nil) + m.OrganizationID = omit.From(val) + } + if !(m.Type.IsValue()) { + val := random_enums_Leadtype(nil) + m.Type = omit.From(val) + } +} + +// insertOptRels creates and inserts any optional the relationships on *models.Lead +// according to the relationships in the template. +// any required relationship should have already exist on the model +func (o *LeadTemplate) insertOptRels(ctx context.Context, exec bob.Executor, m *models.Lead) error { + var err error + + isComplianceReportRequestsDone, _ := leadRelComplianceReportRequestsCtx.Value(ctx) + if !isComplianceReportRequestsDone && o.r.ComplianceReportRequests != nil { + ctx = leadRelComplianceReportRequestsCtx.WithValue(ctx, true) + for _, r := range o.r.ComplianceReportRequests { + if r.o.alreadyPersisted { + m.R.ComplianceReportRequests = append(m.R.ComplianceReportRequests, r.o.Build()) + } else { + rel0, err := r.o.CreateMany(ctx, exec, r.number) + if err != nil { + return err + } + + err = m.AttachComplianceReportRequests(ctx, exec, rel0...) + if err != nil { + return err + } + } + } + } + + isSiteDone, _ := leadRelSiteCtx.Value(ctx) + if !isSiteDone && o.r.Site != nil { + ctx = leadRelSiteCtx.WithValue(ctx, true) + if o.r.Site.o.alreadyPersisted { + m.R.Site = o.r.Site.o.Build() + } else { + var rel3 *models.Site + rel3, err = o.r.Site.o.Create(ctx, exec) + if err != nil { + return err + } + err = m.AttachSite(ctx, exec, rel3) + if err != nil { + return err + } + } + + } + + return err +} + +// Create builds a lead and inserts it into the database +// Relations objects are also inserted and placed in the .R field +func (o *LeadTemplate) Create(ctx context.Context, exec bob.Executor) (*models.Lead, error) { + var err error + opt := o.BuildSetter() + ensureCreatableLead(opt) + + if o.r.CreatorUser == nil { + LeadMods.WithNewCreatorUser().Apply(ctx, o) + } + + var rel1 *models.User + + if o.r.CreatorUser.o.alreadyPersisted { + rel1 = o.r.CreatorUser.o.Build() + } else { + rel1, err = o.r.CreatorUser.o.Create(ctx, exec) + if err != nil { + return nil, err + } + } + + opt.Creator = omit.From(rel1.ID) + + if o.r.Organization == nil { + LeadMods.WithNewOrganization().Apply(ctx, o) + } + + var rel2 *models.Organization + + if o.r.Organization.o.alreadyPersisted { + rel2 = o.r.Organization.o.Build() + } else { + rel2, err = o.r.Organization.o.Create(ctx, exec) + if err != nil { + return nil, err + } + } + + opt.OrganizationID = omit.From(rel2.ID) + + m, err := models.Leads.Insert(opt).One(ctx, exec) + if err != nil { + return nil, err + } + + m.R.CreatorUser = rel1 + m.R.Organization = rel2 + + if err := o.insertOptRels(ctx, exec, m); err != nil { + return nil, err + } + return m, err +} + +// MustCreate builds a lead and inserts it into the database +// Relations objects are also inserted and placed in the .R field +// panics if an error occurs +func (o *LeadTemplate) MustCreate(ctx context.Context, exec bob.Executor) *models.Lead { + m, err := o.Create(ctx, exec) + if err != nil { + panic(err) + } + return m +} + +// CreateOrFail builds a lead and inserts it into the database +// Relations objects are also inserted and placed in the .R field +// It calls `tb.Fatal(err)` on the test/benchmark if an error occurs +func (o *LeadTemplate) CreateOrFail(ctx context.Context, tb testing.TB, exec bob.Executor) *models.Lead { + tb.Helper() + m, err := o.Create(ctx, exec) + if err != nil { + tb.Fatal(err) + return nil + } + return m +} + +// CreateMany builds multiple leads and inserts them into the database +// Relations objects are also inserted and placed in the .R field +func (o LeadTemplate) CreateMany(ctx context.Context, exec bob.Executor, number int) (models.LeadSlice, error) { + var err error + m := make(models.LeadSlice, number) + + for i := range m { + m[i], err = o.Create(ctx, exec) + if err != nil { + return nil, err + } + } + + return m, nil +} + +// MustCreateMany builds multiple leads and inserts them into the database +// Relations objects are also inserted and placed in the .R field +// panics if an error occurs +func (o LeadTemplate) MustCreateMany(ctx context.Context, exec bob.Executor, number int) models.LeadSlice { + m, err := o.CreateMany(ctx, exec, number) + if err != nil { + panic(err) + } + return m +} + +// CreateManyOrFail builds multiple leads and inserts them into the database +// Relations objects are also inserted and placed in the .R field +// It calls `tb.Fatal(err)` on the test/benchmark if an error occurs +func (o LeadTemplate) CreateManyOrFail(ctx context.Context, tb testing.TB, exec bob.Executor, number int) models.LeadSlice { + tb.Helper() + m, err := o.CreateMany(ctx, exec, number) + if err != nil { + tb.Fatal(err) + return nil + } + return m +} + +// Lead has methods that act as mods for the LeadTemplate +var LeadMods leadMods + +type leadMods struct{} + +func (m leadMods) RandomizeAllColumns(f *faker.Faker) LeadMod { + return LeadModSlice{ + LeadMods.RandomCreated(f), + LeadMods.RandomCreator(f), + LeadMods.RandomID(f), + LeadMods.RandomOrganizationID(f), + LeadMods.RandomSiteID(f), + LeadMods.RandomSiteVersion(f), + LeadMods.RandomType(f), + } +} + +// Set the model columns to this value +func (m leadMods) Created(val time.Time) LeadMod { + return LeadModFunc(func(_ context.Context, o *LeadTemplate) { + o.Created = func() time.Time { return val } + }) +} + +// Set the Column from the function +func (m leadMods) CreatedFunc(f func() time.Time) LeadMod { + return LeadModFunc(func(_ context.Context, o *LeadTemplate) { + o.Created = f + }) +} + +// Clear any values for the column +func (m leadMods) UnsetCreated() LeadMod { + return LeadModFunc(func(_ context.Context, o *LeadTemplate) { + o.Created = nil + }) +} + +// Generates a random value for the column using the given faker +// if faker is nil, a default faker is used +func (m leadMods) RandomCreated(f *faker.Faker) LeadMod { + return LeadModFunc(func(_ context.Context, o *LeadTemplate) { + o.Created = func() time.Time { + return random_time_Time(f) + } + }) +} + +// Set the model columns to this value +func (m leadMods) Creator(val int32) LeadMod { + return LeadModFunc(func(_ context.Context, o *LeadTemplate) { + o.Creator = func() int32 { return val } + }) +} + +// Set the Column from the function +func (m leadMods) CreatorFunc(f func() int32) LeadMod { + return LeadModFunc(func(_ context.Context, o *LeadTemplate) { + o.Creator = f + }) +} + +// Clear any values for the column +func (m leadMods) UnsetCreator() LeadMod { + return LeadModFunc(func(_ context.Context, o *LeadTemplate) { + o.Creator = nil + }) +} + +// Generates a random value for the column using the given faker +// if faker is nil, a default faker is used +func (m leadMods) RandomCreator(f *faker.Faker) LeadMod { + return LeadModFunc(func(_ context.Context, o *LeadTemplate) { + o.Creator = func() int32 { + return random_int32(f) + } + }) +} + +// Set the model columns to this value +func (m leadMods) ID(val int32) LeadMod { + return LeadModFunc(func(_ context.Context, o *LeadTemplate) { + o.ID = func() int32 { return val } + }) +} + +// Set the Column from the function +func (m leadMods) IDFunc(f func() int32) LeadMod { + return LeadModFunc(func(_ context.Context, o *LeadTemplate) { + o.ID = f + }) +} + +// Clear any values for the column +func (m leadMods) UnsetID() LeadMod { + return LeadModFunc(func(_ context.Context, o *LeadTemplate) { + o.ID = nil + }) +} + +// Generates a random value for the column using the given faker +// if faker is nil, a default faker is used +func (m leadMods) RandomID(f *faker.Faker) LeadMod { + return LeadModFunc(func(_ context.Context, o *LeadTemplate) { + o.ID = func() int32 { + return random_int32(f) + } + }) +} + +// Set the model columns to this value +func (m leadMods) OrganizationID(val int32) LeadMod { + return LeadModFunc(func(_ context.Context, o *LeadTemplate) { + o.OrganizationID = func() int32 { return val } + }) +} + +// Set the Column from the function +func (m leadMods) OrganizationIDFunc(f func() int32) LeadMod { + return LeadModFunc(func(_ context.Context, o *LeadTemplate) { + o.OrganizationID = f + }) +} + +// Clear any values for the column +func (m leadMods) UnsetOrganizationID() LeadMod { + return LeadModFunc(func(_ context.Context, o *LeadTemplate) { + o.OrganizationID = nil + }) +} + +// Generates a random value for the column using the given faker +// if faker is nil, a default faker is used +func (m leadMods) RandomOrganizationID(f *faker.Faker) LeadMod { + return LeadModFunc(func(_ context.Context, o *LeadTemplate) { + o.OrganizationID = func() int32 { + return random_int32(f) + } + }) +} + +// Set the model columns to this value +func (m leadMods) SiteID(val null.Val[int32]) LeadMod { + return LeadModFunc(func(_ context.Context, o *LeadTemplate) { + o.SiteID = func() null.Val[int32] { return val } + }) +} + +// Set the Column from the function +func (m leadMods) SiteIDFunc(f func() null.Val[int32]) LeadMod { + return LeadModFunc(func(_ context.Context, o *LeadTemplate) { + o.SiteID = f + }) +} + +// Clear any values for the column +func (m leadMods) UnsetSiteID() LeadMod { + return LeadModFunc(func(_ context.Context, o *LeadTemplate) { + o.SiteID = 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 leadMods) RandomSiteID(f *faker.Faker) LeadMod { + return LeadModFunc(func(_ context.Context, o *LeadTemplate) { + o.SiteID = func() null.Val[int32] { + if f == nil { + f = &defaultFaker + } + + val := random_int32(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 leadMods) RandomSiteIDNotNull(f *faker.Faker) LeadMod { + return LeadModFunc(func(_ context.Context, o *LeadTemplate) { + o.SiteID = func() null.Val[int32] { + if f == nil { + f = &defaultFaker + } + + val := random_int32(f) + return null.From(val) + } + }) +} + +// Set the model columns to this value +func (m leadMods) SiteVersion(val null.Val[int32]) LeadMod { + return LeadModFunc(func(_ context.Context, o *LeadTemplate) { + o.SiteVersion = func() null.Val[int32] { return val } + }) +} + +// Set the Column from the function +func (m leadMods) SiteVersionFunc(f func() null.Val[int32]) LeadMod { + return LeadModFunc(func(_ context.Context, o *LeadTemplate) { + o.SiteVersion = f + }) +} + +// Clear any values for the column +func (m leadMods) UnsetSiteVersion() LeadMod { + return LeadModFunc(func(_ context.Context, o *LeadTemplate) { + o.SiteVersion = 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 leadMods) RandomSiteVersion(f *faker.Faker) LeadMod { + return LeadModFunc(func(_ context.Context, o *LeadTemplate) { + o.SiteVersion = func() null.Val[int32] { + if f == nil { + f = &defaultFaker + } + + val := random_int32(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 leadMods) RandomSiteVersionNotNull(f *faker.Faker) LeadMod { + return LeadModFunc(func(_ context.Context, o *LeadTemplate) { + o.SiteVersion = func() null.Val[int32] { + if f == nil { + f = &defaultFaker + } + + val := random_int32(f) + return null.From(val) + } + }) +} + +// Set the model columns to this value +func (m leadMods) Type(val enums.Leadtype) LeadMod { + return LeadModFunc(func(_ context.Context, o *LeadTemplate) { + o.Type = func() enums.Leadtype { return val } + }) +} + +// Set the Column from the function +func (m leadMods) TypeFunc(f func() enums.Leadtype) LeadMod { + return LeadModFunc(func(_ context.Context, o *LeadTemplate) { + o.Type = f + }) +} + +// Clear any values for the column +func (m leadMods) UnsetType() LeadMod { + return LeadModFunc(func(_ context.Context, o *LeadTemplate) { + o.Type = nil + }) +} + +// Generates a random value for the column using the given faker +// if faker is nil, a default faker is used +func (m leadMods) RandomType(f *faker.Faker) LeadMod { + return LeadModFunc(func(_ context.Context, o *LeadTemplate) { + o.Type = func() enums.Leadtype { + return random_enums_Leadtype(f) + } + }) +} + +func (m leadMods) WithParentsCascading() LeadMod { + return LeadModFunc(func(ctx context.Context, o *LeadTemplate) { + if isDone, _ := leadWithParentsCascadingCtx.Value(ctx); isDone { + return + } + ctx = leadWithParentsCascadingCtx.WithValue(ctx, true) + { + + related := o.f.NewUserWithContext(ctx, UserMods.WithParentsCascading()) + m.WithCreatorUser(related).Apply(ctx, o) + } + { + + related := o.f.NewOrganizationWithContext(ctx, OrganizationMods.WithParentsCascading()) + m.WithOrganization(related).Apply(ctx, o) + } + { + + related := o.f.NewSiteWithContext(ctx, SiteMods.WithParentsCascading()) + m.WithSite(related).Apply(ctx, o) + } + }) +} + +func (m leadMods) WithCreatorUser(rel *UserTemplate) LeadMod { + return LeadModFunc(func(ctx context.Context, o *LeadTemplate) { + o.r.CreatorUser = &leadRCreatorUserR{ + o: rel, + } + }) +} + +func (m leadMods) WithNewCreatorUser(mods ...UserMod) LeadMod { + return LeadModFunc(func(ctx context.Context, o *LeadTemplate) { + related := o.f.NewUserWithContext(ctx, mods...) + + m.WithCreatorUser(related).Apply(ctx, o) + }) +} + +func (m leadMods) WithExistingCreatorUser(em *models.User) LeadMod { + return LeadModFunc(func(ctx context.Context, o *LeadTemplate) { + o.r.CreatorUser = &leadRCreatorUserR{ + o: o.f.FromExistingUser(em), + } + }) +} + +func (m leadMods) WithoutCreatorUser() LeadMod { + return LeadModFunc(func(ctx context.Context, o *LeadTemplate) { + o.r.CreatorUser = nil + }) +} + +func (m leadMods) WithOrganization(rel *OrganizationTemplate) LeadMod { + return LeadModFunc(func(ctx context.Context, o *LeadTemplate) { + o.r.Organization = &leadROrganizationR{ + o: rel, + } + }) +} + +func (m leadMods) WithNewOrganization(mods ...OrganizationMod) LeadMod { + return LeadModFunc(func(ctx context.Context, o *LeadTemplate) { + related := o.f.NewOrganizationWithContext(ctx, mods...) + + m.WithOrganization(related).Apply(ctx, o) + }) +} + +func (m leadMods) WithExistingOrganization(em *models.Organization) LeadMod { + return LeadModFunc(func(ctx context.Context, o *LeadTemplate) { + o.r.Organization = &leadROrganizationR{ + o: o.f.FromExistingOrganization(em), + } + }) +} + +func (m leadMods) WithoutOrganization() LeadMod { + return LeadModFunc(func(ctx context.Context, o *LeadTemplate) { + o.r.Organization = nil + }) +} + +func (m leadMods) WithSite(rel *SiteTemplate) LeadMod { + return LeadModFunc(func(ctx context.Context, o *LeadTemplate) { + o.r.Site = &leadRSiteR{ + o: rel, + } + }) +} + +func (m leadMods) WithNewSite(mods ...SiteMod) LeadMod { + return LeadModFunc(func(ctx context.Context, o *LeadTemplate) { + related := o.f.NewSiteWithContext(ctx, mods...) + + m.WithSite(related).Apply(ctx, o) + }) +} + +func (m leadMods) WithExistingSite(em *models.Site) LeadMod { + return LeadModFunc(func(ctx context.Context, o *LeadTemplate) { + o.r.Site = &leadRSiteR{ + o: o.f.FromExistingSite(em), + } + }) +} + +func (m leadMods) WithoutSite() LeadMod { + return LeadModFunc(func(ctx context.Context, o *LeadTemplate) { + o.r.Site = nil + }) +} + +func (m leadMods) WithComplianceReportRequests(number int, related *ComplianceReportRequestTemplate) LeadMod { + return LeadModFunc(func(ctx context.Context, o *LeadTemplate) { + o.r.ComplianceReportRequests = []*leadRComplianceReportRequestsR{{ + number: number, + o: related, + }} + }) +} + +func (m leadMods) WithNewComplianceReportRequests(number int, mods ...ComplianceReportRequestMod) LeadMod { + return LeadModFunc(func(ctx context.Context, o *LeadTemplate) { + related := o.f.NewComplianceReportRequestWithContext(ctx, mods...) + m.WithComplianceReportRequests(number, related).Apply(ctx, o) + }) +} + +func (m leadMods) AddComplianceReportRequests(number int, related *ComplianceReportRequestTemplate) LeadMod { + return LeadModFunc(func(ctx context.Context, o *LeadTemplate) { + o.r.ComplianceReportRequests = append(o.r.ComplianceReportRequests, &leadRComplianceReportRequestsR{ + number: number, + o: related, + }) + }) +} + +func (m leadMods) AddNewComplianceReportRequests(number int, mods ...ComplianceReportRequestMod) LeadMod { + return LeadModFunc(func(ctx context.Context, o *LeadTemplate) { + related := o.f.NewComplianceReportRequestWithContext(ctx, mods...) + m.AddComplianceReportRequests(number, related).Apply(ctx, o) + }) +} + +func (m leadMods) AddExistingComplianceReportRequests(existingModels ...*models.ComplianceReportRequest) LeadMod { + return LeadModFunc(func(ctx context.Context, o *LeadTemplate) { + for _, em := range existingModels { + o.r.ComplianceReportRequests = append(o.r.ComplianceReportRequests, &leadRComplianceReportRequestsR{ + o: o.f.FromExistingComplianceReportRequest(em), + }) + } + }) +} + +func (m leadMods) WithoutComplianceReportRequests() LeadMod { + return LeadModFunc(func(ctx context.Context, o *LeadTemplate) { + o.r.ComplianceReportRequests = nil + }) +} diff --git a/db/factory/organization.bob.go b/db/factory/organization.bob.go index 8704db00..b18da577 100644 --- a/db/factory/organization.bob.go +++ b/db/factory/organization.bob.go @@ -113,6 +113,7 @@ type organizationR struct { FieldseekerSyncs []*organizationRFieldseekerSyncsR Files []*organizationRFilesR H3Aggregations []*organizationRH3AggregationsR + Leads []*organizationRLeadsR NoteAudios []*organizationRNoteAudiosR NoteImages []*organizationRNoteImagesR ArcgisAccountAccount *organizationRArcgisAccountAccountR @@ -264,6 +265,10 @@ type organizationRH3AggregationsR struct { number int o *H3AggregationTemplate } +type organizationRLeadsR struct { + number int + o *LeadTemplate +} type organizationRNoteAudiosR struct { number int o *NoteAudioTemplate @@ -762,6 +767,19 @@ func (t OrganizationTemplate) setModelRels(o *models.Organization) { o.R.H3Aggregations = rel } + if t.r.Leads != nil { + rel := models.LeadSlice{} + for _, r := range t.r.Leads { + related := r.o.BuildMany(r.number) + for _, rel := range related { + rel.OrganizationID = o.ID // h2 + rel.R.Organization = o + } + rel = append(rel, related...) + } + o.R.Leads = rel + } + if t.r.NoteAudios != nil { rel := models.NoteAudioSlice{} for _, r := range t.r.NoteAudios { @@ -1811,6 +1829,26 @@ func (o *OrganizationTemplate) insertOptRels(ctx context.Context, exec bob.Execu } } + isLeadsDone, _ := organizationRelLeadsCtx.Value(ctx) + if !isLeadsDone && o.r.Leads != nil { + ctx = organizationRelLeadsCtx.WithValue(ctx, true) + for _, r := range o.r.Leads { + if r.o.alreadyPersisted { + m.R.Leads = append(m.R.Leads, r.o.Build()) + } else { + rel35, err := r.o.CreateMany(ctx, exec, r.number) + if err != nil { + return err + } + + err = m.AttachLeads(ctx, exec, rel35...) + if err != nil { + return err + } + } + } + } + isNoteAudiosDone, _ := organizationRelNoteAudiosCtx.Value(ctx) if !isNoteAudiosDone && o.r.NoteAudios != nil { ctx = organizationRelNoteAudiosCtx.WithValue(ctx, true) @@ -1818,12 +1856,12 @@ func (o *OrganizationTemplate) insertOptRels(ctx context.Context, exec bob.Execu if r.o.alreadyPersisted { m.R.NoteAudios = append(m.R.NoteAudios, r.o.Build()) } else { - rel35, err := r.o.CreateMany(ctx, exec, r.number) + rel36, err := r.o.CreateMany(ctx, exec, r.number) if err != nil { return err } - err = m.AttachNoteAudios(ctx, exec, rel35...) + err = m.AttachNoteAudios(ctx, exec, rel36...) if err != nil { return err } @@ -1838,12 +1876,12 @@ func (o *OrganizationTemplate) insertOptRels(ctx context.Context, exec bob.Execu if r.o.alreadyPersisted { m.R.NoteImages = append(m.R.NoteImages, r.o.Build()) } else { - rel36, err := r.o.CreateMany(ctx, exec, r.number) + rel37, err := r.o.CreateMany(ctx, exec, r.number) if err != nil { return err } - err = m.AttachNoteImages(ctx, exec, rel36...) + err = m.AttachNoteImages(ctx, exec, rel37...) if err != nil { return err } @@ -1857,12 +1895,12 @@ func (o *OrganizationTemplate) insertOptRels(ctx context.Context, exec bob.Execu if o.r.ArcgisAccountAccount.o.alreadyPersisted { m.R.ArcgisAccountAccount = o.r.ArcgisAccountAccount.o.Build() } else { - var rel37 *models.ArcgisAccount - rel37, err = o.r.ArcgisAccountAccount.o.Create(ctx, exec) + var rel38 *models.ArcgisAccount + rel38, err = o.r.ArcgisAccountAccount.o.Create(ctx, exec) if err != nil { return err } - err = m.AttachArcgisAccountAccount(ctx, exec, rel37) + err = m.AttachArcgisAccountAccount(ctx, exec, rel38) if err != nil { return err } @@ -1876,12 +1914,12 @@ func (o *OrganizationTemplate) insertOptRels(ctx context.Context, exec bob.Execu if o.r.FieldseekerServiceFeatureItemServiceFeature.o.alreadyPersisted { m.R.FieldseekerServiceFeatureItemServiceFeature = o.r.FieldseekerServiceFeatureItemServiceFeature.o.Build() } else { - var rel38 *models.ArcgisServiceFeature - rel38, err = o.r.FieldseekerServiceFeatureItemServiceFeature.o.Create(ctx, exec) + var rel39 *models.ArcgisServiceFeature + rel39, err = o.r.FieldseekerServiceFeatureItemServiceFeature.o.Create(ctx, exec) if err != nil { return err } - err = m.AttachFieldseekerServiceFeatureItemServiceFeature(ctx, exec, rel38) + err = m.AttachFieldseekerServiceFeatureItemServiceFeature(ctx, exec, rel39) if err != nil { return err } @@ -1896,12 +1934,12 @@ func (o *OrganizationTemplate) insertOptRels(ctx context.Context, exec bob.Execu if r.o.alreadyPersisted { m.R.Nuisances = append(m.R.Nuisances, r.o.Build()) } else { - rel39, err := r.o.CreateMany(ctx, exec, r.number) + rel40, err := r.o.CreateMany(ctx, exec, r.number) if err != nil { return err } - err = m.AttachNuisances(ctx, exec, rel39...) + err = m.AttachNuisances(ctx, exec, rel40...) if err != nil { return err } @@ -1916,12 +1954,12 @@ func (o *OrganizationTemplate) insertOptRels(ctx context.Context, exec bob.Execu if r.o.alreadyPersisted { m.R.PublicreportPool = append(m.R.PublicreportPool, r.o.Build()) } else { - rel40, err := r.o.CreateMany(ctx, exec, r.number) + rel41, err := r.o.CreateMany(ctx, exec, r.number) if err != nil { return err } - err = m.AttachPublicreportPool(ctx, exec, rel40...) + err = m.AttachPublicreportPool(ctx, exec, rel41...) if err != nil { return err } @@ -1936,12 +1974,12 @@ func (o *OrganizationTemplate) insertOptRels(ctx context.Context, exec bob.Execu if r.o.alreadyPersisted { m.R.Quicks = append(m.R.Quicks, r.o.Build()) } else { - rel41, err := r.o.CreateMany(ctx, exec, r.number) + rel42, err := r.o.CreateMany(ctx, exec, r.number) if err != nil { return err } - err = m.AttachQuicks(ctx, exec, rel41...) + err = m.AttachQuicks(ctx, exec, rel42...) if err != nil { return err } @@ -1956,12 +1994,12 @@ func (o *OrganizationTemplate) insertOptRels(ctx context.Context, exec bob.Execu if r.o.alreadyPersisted { m.R.Signals = append(m.R.Signals, r.o.Build()) } else { - rel42, err := r.o.CreateMany(ctx, exec, r.number) + rel43, err := r.o.CreateMany(ctx, exec, r.number) if err != nil { return err } - err = m.AttachSignals(ctx, exec, rel42...) + err = m.AttachSignals(ctx, exec, rel43...) if err != nil { return err } @@ -1976,12 +2014,12 @@ func (o *OrganizationTemplate) insertOptRels(ctx context.Context, exec bob.Execu if r.o.alreadyPersisted { m.R.User = append(m.R.User, r.o.Build()) } else { - rel43, err := r.o.CreateMany(ctx, exec, r.number) + rel44, err := r.o.CreateMany(ctx, exec, r.number) if err != nil { return err } - err = m.AttachUser(ctx, exec, rel43...) + err = m.AttachUser(ctx, exec, rel44...) if err != nil { return err } @@ -5527,6 +5565,54 @@ func (m organizationMods) WithoutH3Aggregations() OrganizationMod { }) } +func (m organizationMods) WithLeads(number int, related *LeadTemplate) OrganizationMod { + return OrganizationModFunc(func(ctx context.Context, o *OrganizationTemplate) { + o.r.Leads = []*organizationRLeadsR{{ + number: number, + o: related, + }} + }) +} + +func (m organizationMods) WithNewLeads(number int, mods ...LeadMod) OrganizationMod { + return OrganizationModFunc(func(ctx context.Context, o *OrganizationTemplate) { + related := o.f.NewLeadWithContext(ctx, mods...) + m.WithLeads(number, related).Apply(ctx, o) + }) +} + +func (m organizationMods) AddLeads(number int, related *LeadTemplate) OrganizationMod { + return OrganizationModFunc(func(ctx context.Context, o *OrganizationTemplate) { + o.r.Leads = append(o.r.Leads, &organizationRLeadsR{ + number: number, + o: related, + }) + }) +} + +func (m organizationMods) AddNewLeads(number int, mods ...LeadMod) OrganizationMod { + return OrganizationModFunc(func(ctx context.Context, o *OrganizationTemplate) { + related := o.f.NewLeadWithContext(ctx, mods...) + m.AddLeads(number, related).Apply(ctx, o) + }) +} + +func (m organizationMods) AddExistingLeads(existingModels ...*models.Lead) OrganizationMod { + return OrganizationModFunc(func(ctx context.Context, o *OrganizationTemplate) { + for _, em := range existingModels { + o.r.Leads = append(o.r.Leads, &organizationRLeadsR{ + o: o.f.FromExistingLead(em), + }) + } + }) +} + +func (m organizationMods) WithoutLeads() OrganizationMod { + return OrganizationModFunc(func(ctx context.Context, o *OrganizationTemplate) { + o.r.Leads = nil + }) +} + func (m organizationMods) WithNoteAudios(number int, related *NoteAudioTemplate) OrganizationMod { return OrganizationModFunc(func(ctx context.Context, o *OrganizationTemplate) { o.r.NoteAudios = []*organizationRNoteAudiosR{{ diff --git a/db/factory/site.bob.go b/db/factory/site.bob.go index ddaad081..ada316d4 100644 --- a/db/factory/site.bob.go +++ b/db/factory/site.bob.go @@ -59,18 +59,18 @@ type SiteTemplate struct { } type siteR struct { - ComplianceReportRequests []*siteRComplianceReportRequestsR - Pools []*siteRPoolsR - Residents []*siteRResidentsR - Address *siteRAddressR - CreatorUser *siteRCreatorUserR - File *siteRFileR - Parcel *siteRParcelR + Leads []*siteRLeadsR + Pools []*siteRPoolsR + Residents []*siteRResidentsR + Address *siteRAddressR + CreatorUser *siteRCreatorUserR + File *siteRFileR + Parcel *siteRParcelR } -type siteRComplianceReportRequestsR struct { +type siteRLeadsR struct { number int - o *ComplianceReportRequestTemplate + o *LeadTemplate } type siteRPoolsR struct { number int @@ -103,18 +103,18 @@ func (o *SiteTemplate) Apply(ctx context.Context, mods ...SiteMod) { // setModelRels creates and sets the relationships on *models.Site // according to the relationships in the template. Nothing is inserted into the db func (t SiteTemplate) setModelRels(o *models.Site) { - if t.r.ComplianceReportRequests != nil { - rel := models.ComplianceReportRequestSlice{} - for _, r := range t.r.ComplianceReportRequests { + if t.r.Leads != nil { + rel := models.LeadSlice{} + for _, r := range t.r.Leads { related := r.o.BuildMany(r.number) for _, rel := range related { - rel.SiteID = o.ID // h2 - rel.SiteVersion = o.Version // h2 + rel.SiteID = null.From(o.ID) // h2 + rel.SiteVersion = null.From(o.Version) // h2 rel.R.Site = o } rel = append(rel, related...) } - o.R.ComplianceReportRequests = rel + o.R.Leads = rel } if t.r.Pools != nil { @@ -356,19 +356,19 @@ func ensureCreatableSite(m *models.SiteSetter) { func (o *SiteTemplate) insertOptRels(ctx context.Context, exec bob.Executor, m *models.Site) error { var err error - isComplianceReportRequestsDone, _ := siteRelComplianceReportRequestsCtx.Value(ctx) - if !isComplianceReportRequestsDone && o.r.ComplianceReportRequests != nil { - ctx = siteRelComplianceReportRequestsCtx.WithValue(ctx, true) - for _, r := range o.r.ComplianceReportRequests { + isLeadsDone, _ := siteRelLeadsCtx.Value(ctx) + if !isLeadsDone && o.r.Leads != nil { + ctx = siteRelLeadsCtx.WithValue(ctx, true) + for _, r := range o.r.Leads { if r.o.alreadyPersisted { - m.R.ComplianceReportRequests = append(m.R.ComplianceReportRequests, r.o.Build()) + m.R.Leads = append(m.R.Leads, r.o.Build()) } else { rel0, err := r.o.CreateMany(ctx, exec, r.number) if err != nil { return err } - err = m.AttachComplianceReportRequests(ctx, exec, rel0...) + err = m.AttachLeads(ctx, exec, rel0...) if err != nil { return err } @@ -1216,51 +1216,51 @@ func (m siteMods) WithoutParcel() SiteMod { }) } -func (m siteMods) WithComplianceReportRequests(number int, related *ComplianceReportRequestTemplate) SiteMod { +func (m siteMods) WithLeads(number int, related *LeadTemplate) SiteMod { return SiteModFunc(func(ctx context.Context, o *SiteTemplate) { - o.r.ComplianceReportRequests = []*siteRComplianceReportRequestsR{{ + o.r.Leads = []*siteRLeadsR{{ number: number, o: related, }} }) } -func (m siteMods) WithNewComplianceReportRequests(number int, mods ...ComplianceReportRequestMod) SiteMod { +func (m siteMods) WithNewLeads(number int, mods ...LeadMod) SiteMod { return SiteModFunc(func(ctx context.Context, o *SiteTemplate) { - related := o.f.NewComplianceReportRequestWithContext(ctx, mods...) - m.WithComplianceReportRequests(number, related).Apply(ctx, o) + related := o.f.NewLeadWithContext(ctx, mods...) + m.WithLeads(number, related).Apply(ctx, o) }) } -func (m siteMods) AddComplianceReportRequests(number int, related *ComplianceReportRequestTemplate) SiteMod { +func (m siteMods) AddLeads(number int, related *LeadTemplate) SiteMod { return SiteModFunc(func(ctx context.Context, o *SiteTemplate) { - o.r.ComplianceReportRequests = append(o.r.ComplianceReportRequests, &siteRComplianceReportRequestsR{ + o.r.Leads = append(o.r.Leads, &siteRLeadsR{ number: number, o: related, }) }) } -func (m siteMods) AddNewComplianceReportRequests(number int, mods ...ComplianceReportRequestMod) SiteMod { +func (m siteMods) AddNewLeads(number int, mods ...LeadMod) SiteMod { return SiteModFunc(func(ctx context.Context, o *SiteTemplate) { - related := o.f.NewComplianceReportRequestWithContext(ctx, mods...) - m.AddComplianceReportRequests(number, related).Apply(ctx, o) + related := o.f.NewLeadWithContext(ctx, mods...) + m.AddLeads(number, related).Apply(ctx, o) }) } -func (m siteMods) AddExistingComplianceReportRequests(existingModels ...*models.ComplianceReportRequest) SiteMod { +func (m siteMods) AddExistingLeads(existingModels ...*models.Lead) SiteMod { return SiteModFunc(func(ctx context.Context, o *SiteTemplate) { for _, em := range existingModels { - o.r.ComplianceReportRequests = append(o.r.ComplianceReportRequests, &siteRComplianceReportRequestsR{ - o: o.f.FromExistingComplianceReportRequest(em), + o.r.Leads = append(o.r.Leads, &siteRLeadsR{ + o: o.f.FromExistingLead(em), }) } }) } -func (m siteMods) WithoutComplianceReportRequests() SiteMod { +func (m siteMods) WithoutLeads() SiteMod { return SiteModFunc(func(ctx context.Context, o *SiteTemplate) { - o.r.ComplianceReportRequests = nil + o.r.Leads = nil }) } diff --git a/db/factory/user_.bob.go b/db/factory/user_.bob.go index 34c8a1b2..761ff2e1 100644 --- a/db/factory/user_.bob.go +++ b/db/factory/user_.bob.go @@ -62,8 +62,10 @@ type userR struct { UserOauthTokens []*userRUserOauthTokensR PublicUserUser []*userRPublicUserUserR CreatorComplianceReportRequests []*userRCreatorComplianceReportRequestsR + CommitterFiles []*userRCommitterFilesR CreatorFiles []*userRCreatorFilesR FileuploadPool []*userRFileuploadPoolR + CreatorLeads []*userRCreatorLeadsR CreatorNoteAudios []*userRCreatorNoteAudiosR DeletorNoteAudios []*userRDeletorNoteAudiosR CreatorNoteImages []*userRCreatorNoteImagesR @@ -89,6 +91,10 @@ type userRCreatorComplianceReportRequestsR struct { number int o *ComplianceReportRequestTemplate } +type userRCommitterFilesR struct { + number int + o *FileuploadFileTemplate +} type userRCreatorFilesR struct { number int o *FileuploadFileTemplate @@ -97,6 +103,10 @@ type userRFileuploadPoolR struct { number int o *FileuploadPoolTemplate } +type userRCreatorLeadsR struct { + number int + o *LeadTemplate +} type userRCreatorNoteAudiosR struct { number int o *NoteAudioTemplate @@ -190,6 +200,19 @@ func (t UserTemplate) setModelRels(o *models.User) { o.R.CreatorComplianceReportRequests = rel } + if t.r.CommitterFiles != nil { + rel := models.FileuploadFileSlice{} + for _, r := range t.r.CommitterFiles { + related := r.o.BuildMany(r.number) + for _, rel := range related { + rel.Committer = null.From(o.ID) // h2 + rel.R.CommitterUser = o + } + rel = append(rel, related...) + } + o.R.CommitterFiles = rel + } + if t.r.CreatorFiles != nil { rel := models.FileuploadFileSlice{} for _, r := range t.r.CreatorFiles { @@ -216,6 +239,19 @@ func (t UserTemplate) setModelRels(o *models.User) { o.R.FileuploadPool = rel } + if t.r.CreatorLeads != nil { + rel := models.LeadSlice{} + for _, r := range t.r.CreatorLeads { + related := r.o.BuildMany(r.number) + for _, rel := range related { + rel.Creator = o.ID // h2 + rel.R.CreatorUser = o + } + rel = append(rel, related...) + } + o.R.CreatorLeads = rel + } + if t.r.CreatorNoteAudios != nil { rel := models.NoteAudioSlice{} for _, r := range t.r.CreatorNoteAudios { @@ -584,6 +620,26 @@ func (o *UserTemplate) insertOptRels(ctx context.Context, exec bob.Executor, m * } } + isCommitterFilesDone, _ := userRelCommitterFilesCtx.Value(ctx) + if !isCommitterFilesDone && o.r.CommitterFiles != nil { + ctx = userRelCommitterFilesCtx.WithValue(ctx, true) + for _, r := range o.r.CommitterFiles { + if r.o.alreadyPersisted { + m.R.CommitterFiles = append(m.R.CommitterFiles, r.o.Build()) + } else { + rel3, err := r.o.CreateMany(ctx, exec, r.number) + if err != nil { + return err + } + + err = m.AttachCommitterFiles(ctx, exec, rel3...) + if err != nil { + return err + } + } + } + } + isCreatorFilesDone, _ := userRelCreatorFilesCtx.Value(ctx) if !isCreatorFilesDone && o.r.CreatorFiles != nil { ctx = userRelCreatorFilesCtx.WithValue(ctx, true) @@ -591,12 +647,12 @@ func (o *UserTemplate) insertOptRels(ctx context.Context, exec bob.Executor, m * if r.o.alreadyPersisted { m.R.CreatorFiles = append(m.R.CreatorFiles, r.o.Build()) } else { - rel3, err := r.o.CreateMany(ctx, exec, r.number) + rel4, err := r.o.CreateMany(ctx, exec, r.number) if err != nil { return err } - err = m.AttachCreatorFiles(ctx, exec, rel3...) + err = m.AttachCreatorFiles(ctx, exec, rel4...) if err != nil { return err } @@ -611,12 +667,32 @@ func (o *UserTemplate) insertOptRels(ctx context.Context, exec bob.Executor, m * if r.o.alreadyPersisted { m.R.FileuploadPool = append(m.R.FileuploadPool, r.o.Build()) } else { - rel4, err := r.o.CreateMany(ctx, exec, r.number) + rel5, err := r.o.CreateMany(ctx, exec, r.number) if err != nil { return err } - err = m.AttachFileuploadPool(ctx, exec, rel4...) + err = m.AttachFileuploadPool(ctx, exec, rel5...) + if err != nil { + return err + } + } + } + } + + isCreatorLeadsDone, _ := userRelCreatorLeadsCtx.Value(ctx) + if !isCreatorLeadsDone && o.r.CreatorLeads != nil { + ctx = userRelCreatorLeadsCtx.WithValue(ctx, true) + for _, r := range o.r.CreatorLeads { + if r.o.alreadyPersisted { + m.R.CreatorLeads = append(m.R.CreatorLeads, r.o.Build()) + } else { + rel6, err := r.o.CreateMany(ctx, exec, r.number) + if err != nil { + return err + } + + err = m.AttachCreatorLeads(ctx, exec, rel6...) if err != nil { return err } @@ -631,12 +707,12 @@ func (o *UserTemplate) insertOptRels(ctx context.Context, exec bob.Executor, m * if r.o.alreadyPersisted { m.R.CreatorNoteAudios = append(m.R.CreatorNoteAudios, 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.AttachCreatorNoteAudios(ctx, exec, rel5...) + err = m.AttachCreatorNoteAudios(ctx, exec, rel7...) if err != nil { return err } @@ -651,12 +727,12 @@ func (o *UserTemplate) insertOptRels(ctx context.Context, exec bob.Executor, m * if r.o.alreadyPersisted { m.R.DeletorNoteAudios = append(m.R.DeletorNoteAudios, 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.AttachDeletorNoteAudios(ctx, exec, rel6...) + err = m.AttachDeletorNoteAudios(ctx, exec, rel8...) if err != nil { return err } @@ -671,12 +747,12 @@ func (o *UserTemplate) insertOptRels(ctx context.Context, exec bob.Executor, m * if r.o.alreadyPersisted { m.R.CreatorNoteImages = append(m.R.CreatorNoteImages, r.o.Build()) } else { - rel7, err := r.o.CreateMany(ctx, exec, r.number) + rel9, err := r.o.CreateMany(ctx, exec, r.number) if err != nil { return err } - err = m.AttachCreatorNoteImages(ctx, exec, rel7...) + err = m.AttachCreatorNoteImages(ctx, exec, rel9...) if err != nil { return err } @@ -691,12 +767,12 @@ func (o *UserTemplate) insertOptRels(ctx context.Context, exec bob.Executor, m * if r.o.alreadyPersisted { m.R.DeletorNoteImages = append(m.R.DeletorNoteImages, r.o.Build()) } else { - rel8, err := r.o.CreateMany(ctx, exec, r.number) + rel10, err := r.o.CreateMany(ctx, exec, r.number) if err != nil { return err } - err = m.AttachDeletorNoteImages(ctx, exec, rel8...) + err = m.AttachDeletorNoteImages(ctx, exec, rel10...) if err != nil { return err } @@ -711,12 +787,12 @@ func (o *UserTemplate) insertOptRels(ctx context.Context, exec bob.Executor, m * if r.o.alreadyPersisted { m.R.UserNotifications = append(m.R.UserNotifications, r.o.Build()) } else { - rel9, err := r.o.CreateMany(ctx, exec, r.number) + rel11, err := r.o.CreateMany(ctx, exec, r.number) if err != nil { return err } - err = m.AttachUserNotifications(ctx, exec, rel9...) + err = m.AttachUserNotifications(ctx, exec, rel11...) if err != nil { return err } @@ -731,12 +807,12 @@ func (o *UserTemplate) insertOptRels(ctx context.Context, exec bob.Executor, m * if r.o.alreadyPersisted { m.R.CreatorPools = append(m.R.CreatorPools, r.o.Build()) } else { - rel10, err := r.o.CreateMany(ctx, exec, r.number) + rel12, err := r.o.CreateMany(ctx, exec, r.number) if err != nil { return err } - err = m.AttachCreatorPools(ctx, exec, rel10...) + err = m.AttachCreatorPools(ctx, exec, rel12...) if err != nil { return err } @@ -751,12 +827,12 @@ func (o *UserTemplate) insertOptRels(ctx context.Context, exec bob.Executor, m * if r.o.alreadyPersisted { m.R.CreatorResidents = append(m.R.CreatorResidents, r.o.Build()) } else { - rel11, err := r.o.CreateMany(ctx, exec, r.number) + rel13, err := r.o.CreateMany(ctx, exec, r.number) if err != nil { return err } - err = m.AttachCreatorResidents(ctx, exec, rel11...) + err = m.AttachCreatorResidents(ctx, exec, rel13...) if err != nil { return err } @@ -771,12 +847,12 @@ func (o *UserTemplate) insertOptRels(ctx context.Context, exec bob.Executor, m * if r.o.alreadyPersisted { m.R.AddressorSignals = append(m.R.AddressorSignals, r.o.Build()) } else { - rel12, err := r.o.CreateMany(ctx, exec, r.number) + rel14, err := r.o.CreateMany(ctx, exec, r.number) if err != nil { return err } - err = m.AttachAddressorSignals(ctx, exec, rel12...) + err = m.AttachAddressorSignals(ctx, exec, rel14...) if err != nil { return err } @@ -791,12 +867,12 @@ func (o *UserTemplate) insertOptRels(ctx context.Context, exec bob.Executor, m * if r.o.alreadyPersisted { m.R.CreatorSignals = append(m.R.CreatorSignals, r.o.Build()) } else { - rel13, err := r.o.CreateMany(ctx, exec, r.number) + rel15, err := r.o.CreateMany(ctx, exec, r.number) if err != nil { return err } - err = m.AttachCreatorSignals(ctx, exec, rel13...) + err = m.AttachCreatorSignals(ctx, exec, rel15...) if err != nil { return err } @@ -811,12 +887,12 @@ func (o *UserTemplate) insertOptRels(ctx context.Context, exec bob.Executor, m * if r.o.alreadyPersisted { m.R.CreatorSites = append(m.R.CreatorSites, r.o.Build()) } else { - rel14, err := r.o.CreateMany(ctx, exec, r.number) + rel16, err := r.o.CreateMany(ctx, exec, r.number) if err != nil { return err } - err = m.AttachCreatorSites(ctx, exec, rel14...) + err = m.AttachCreatorSites(ctx, exec, rel16...) if err != nil { return err } @@ -838,25 +914,25 @@ func (o *UserTemplate) Create(ctx context.Context, exec bob.Executor) (*models.U UserMods.WithNewOrganization().Apply(ctx, o) } - var rel15 *models.Organization + var rel17 *models.Organization if o.r.Organization.o.alreadyPersisted { - rel15 = o.r.Organization.o.Build() + rel17 = o.r.Organization.o.Build() } else { - rel15, err = o.r.Organization.o.Create(ctx, exec) + rel17, err = o.r.Organization.o.Create(ctx, exec) if err != nil { return nil, err } } - opt.OrganizationID = omit.From(rel15.ID) + opt.OrganizationID = omit.From(rel17.ID) m, err := models.Users.Insert(opt).One(ctx, exec) if err != nil { return nil, err } - m.R.Organization = rel15 + m.R.Organization = rel17 if err := o.insertOptRels(ctx, exec, m); err != nil { return nil, err @@ -1674,6 +1750,54 @@ func (m userMods) WithoutCreatorComplianceReportRequests() UserMod { }) } +func (m userMods) WithCommitterFiles(number int, related *FileuploadFileTemplate) UserMod { + return UserModFunc(func(ctx context.Context, o *UserTemplate) { + o.r.CommitterFiles = []*userRCommitterFilesR{{ + number: number, + o: related, + }} + }) +} + +func (m userMods) WithNewCommitterFiles(number int, mods ...FileuploadFileMod) UserMod { + return UserModFunc(func(ctx context.Context, o *UserTemplate) { + related := o.f.NewFileuploadFileWithContext(ctx, mods...) + m.WithCommitterFiles(number, related).Apply(ctx, o) + }) +} + +func (m userMods) AddCommitterFiles(number int, related *FileuploadFileTemplate) UserMod { + return UserModFunc(func(ctx context.Context, o *UserTemplate) { + o.r.CommitterFiles = append(o.r.CommitterFiles, &userRCommitterFilesR{ + number: number, + o: related, + }) + }) +} + +func (m userMods) AddNewCommitterFiles(number int, mods ...FileuploadFileMod) UserMod { + return UserModFunc(func(ctx context.Context, o *UserTemplate) { + related := o.f.NewFileuploadFileWithContext(ctx, mods...) + m.AddCommitterFiles(number, related).Apply(ctx, o) + }) +} + +func (m userMods) AddExistingCommitterFiles(existingModels ...*models.FileuploadFile) UserMod { + return UserModFunc(func(ctx context.Context, o *UserTemplate) { + for _, em := range existingModels { + o.r.CommitterFiles = append(o.r.CommitterFiles, &userRCommitterFilesR{ + o: o.f.FromExistingFileuploadFile(em), + }) + } + }) +} + +func (m userMods) WithoutCommitterFiles() UserMod { + return UserModFunc(func(ctx context.Context, o *UserTemplate) { + o.r.CommitterFiles = nil + }) +} + func (m userMods) WithCreatorFiles(number int, related *FileuploadFileTemplate) UserMod { return UserModFunc(func(ctx context.Context, o *UserTemplate) { o.r.CreatorFiles = []*userRCreatorFilesR{{ @@ -1770,6 +1894,54 @@ func (m userMods) WithoutFileuploadPool() UserMod { }) } +func (m userMods) WithCreatorLeads(number int, related *LeadTemplate) UserMod { + return UserModFunc(func(ctx context.Context, o *UserTemplate) { + o.r.CreatorLeads = []*userRCreatorLeadsR{{ + number: number, + o: related, + }} + }) +} + +func (m userMods) WithNewCreatorLeads(number int, mods ...LeadMod) UserMod { + return UserModFunc(func(ctx context.Context, o *UserTemplate) { + related := o.f.NewLeadWithContext(ctx, mods...) + m.WithCreatorLeads(number, related).Apply(ctx, o) + }) +} + +func (m userMods) AddCreatorLeads(number int, related *LeadTemplate) UserMod { + return UserModFunc(func(ctx context.Context, o *UserTemplate) { + o.r.CreatorLeads = append(o.r.CreatorLeads, &userRCreatorLeadsR{ + number: number, + o: related, + }) + }) +} + +func (m userMods) AddNewCreatorLeads(number int, mods ...LeadMod) UserMod { + return UserModFunc(func(ctx context.Context, o *UserTemplate) { + related := o.f.NewLeadWithContext(ctx, mods...) + m.AddCreatorLeads(number, related).Apply(ctx, o) + }) +} + +func (m userMods) AddExistingCreatorLeads(existingModels ...*models.Lead) UserMod { + return UserModFunc(func(ctx context.Context, o *UserTemplate) { + for _, em := range existingModels { + o.r.CreatorLeads = append(o.r.CreatorLeads, &userRCreatorLeadsR{ + o: o.f.FromExistingLead(em), + }) + } + }) +} + +func (m userMods) WithoutCreatorLeads() UserMod { + return UserModFunc(func(ctx context.Context, o *UserTemplate) { + o.r.CreatorLeads = nil + }) +} + func (m userMods) WithCreatorNoteAudios(number int, related *NoteAudioTemplate) UserMod { return UserModFunc(func(ctx context.Context, o *UserTemplate) { o.r.CreatorNoteAudios = []*userRCreatorNoteAudiosR{{ diff --git a/db/migrations/00080_signal.sql b/db/migrations/00080_signal.sql index ece3e291..efa36c6f 100644 --- a/db/migrations/00080_signal.sql +++ b/db/migrations/00080_signal.sql @@ -1,14 +1,15 @@ -- +goose Up CREATE TYPE SignalType AS ENUM ( - 'flyover.pool', - 'plan.followup', - 'publicreport.water', - 'publicreport.nuisance', - 'residual.exiring', - 'surveillance.observation', - 'trap.spike' + 'flyover pool', + 'plan followup', + 'publicreport water', + 'publicreport nuisance', + 'residual exiring', + 'surveillance observation', + 'trap spike' ); CREATE TYPE MosquitoSpecies AS ENUM ( + 'none', 'aedes aegypti', 'aedes albopictus', 'culex pipiens', diff --git a/db/migrations/00084_lead.sql b/db/migrations/00084_lead.sql new file mode 100644 index 00000000..34b0ef87 --- /dev/null +++ b/db/migrations/00084_lead.sql @@ -0,0 +1,29 @@ +-- +goose Up +CREATE TYPE LeadType AS ENUM ( + 'green-pool' +); +CREATE TABLE lead ( + created TIMESTAMP WITHOUT TIME ZONE NOT NULL, + creator INTEGER NOT NULL REFERENCES user_(id), + id SERIAL NOT NULL, + organization_id INTEGER NOT NULL REFERENCES organization(id), + site_id INTEGER, + site_version INTEGER, + type_ LeadType NOT NULL, + FOREIGN KEY (site_id, site_version) REFERENCES site(id, version), + PRIMARY KEY (id) + +); +ALTER TABLE compliance_report_request + DROP CONSTRAINT compliance_report_request_site_id_site_version_fkey, + DROP COLUMN site_id, + DROP COLUMN site_version, + ADD COLUMN lead_id INTEGER REFERENCES lead(id); +-- +goose Down +ALTER TABLE compliance_report_request + DROP COLUMN lead_id, + ADD COLUMN site_id INTEGER, + ADD COLUMN site_version INTEGER, + ADD FOREIGN KEY (site_id, site_version) REFERENCES site(id, version); +DROP TABLE lead; +DROP TYPE LeadType; diff --git a/db/migrations/00085_file_committer.sql b/db/migrations/00085_file_committer.sql new file mode 100644 index 00000000..99e89943 --- /dev/null +++ b/db/migrations/00085_file_committer.sql @@ -0,0 +1,4 @@ +-- +goose Up +ALTER TABLE fileupload.file ADD COLUMN committer INTEGER REFERENCES user_(id); +-- +goose Down +ALTER TABLE fileupload.file DROP COLUMN committer; diff --git a/db/migrations/00086_drop_fileupload_pool_condition.sql b/db/migrations/00086_drop_fileupload_pool_condition.sql new file mode 100644 index 00000000..e038e8d7 --- /dev/null +++ b/db/migrations/00086_drop_fileupload_pool_condition.sql @@ -0,0 +1,16 @@ +-- +goose Up +ALTER TYPE PoolConditionType ADD VALUE 'unknown' AFTER 'false pool'; +ALTER TABLE fileupload.pool DROP COLUMN condition; +DROP TYPE fileupload.PoolConditionType; +ALTER TABLE fileupload.pool ADD COLUMN condition PoolConditionType NOT NULL; +-- +goose Down +ALTER TABLE fileupload.pool DROP COLUMN condition; +CREATE TYPE fileupload.PoolConditionType AS ENUM ( + 'green', + 'murky', + 'blue', + 'dry', + 'false pool', + 'unknown' +); +ALTER TABLE fileupload.pool ADD COLUMN condition fileupload.PoolConditionType NOT NULL; diff --git a/db/models/bob_counts.bob.go b/db/models/bob_counts.bob.go index a8382b34..23b567d0 100644 --- a/db/models/bob_counts.bob.go +++ b/db/models/bob_counts.bob.go @@ -34,6 +34,7 @@ type preloadCounts struct { ComplianceReportRequest complianceReportRequestCountPreloader FileuploadCSV fileuploadCSVCountPreloader FileuploadFile fileuploadFileCountPreloader + Lead leadCountPreloader NoteAudio noteAudioCountPreloader NoteImage noteImageCountPreloader Organization organizationCountPreloader @@ -63,6 +64,7 @@ func getPreloadCount() preloadCounts { ComplianceReportRequest: buildComplianceReportRequestCountPreloader(), FileuploadCSV: buildFileuploadCSVCountPreloader(), FileuploadFile: buildFileuploadFileCountPreloader(), + Lead: buildLeadCountPreloader(), NoteAudio: buildNoteAudioCountPreloader(), NoteImage: buildNoteImageCountPreloader(), Organization: buildOrganizationCountPreloader(), @@ -92,6 +94,7 @@ type thenLoadCounts[Q orm.Loadable] struct { ComplianceReportRequest complianceReportRequestCountThenLoader[Q] FileuploadCSV fileuploadCSVCountThenLoader[Q] FileuploadFile fileuploadFileCountThenLoader[Q] + Lead leadCountThenLoader[Q] NoteAudio noteAudioCountThenLoader[Q] NoteImage noteImageCountThenLoader[Q] Organization organizationCountThenLoader[Q] @@ -121,6 +124,7 @@ func getThenLoadCount[Q orm.Loadable]() thenLoadCounts[Q] { ComplianceReportRequest: buildComplianceReportRequestCountThenLoader[Q](), FileuploadCSV: buildFileuploadCSVCountThenLoader[Q](), FileuploadFile: buildFileuploadFileCountThenLoader[Q](), + Lead: buildLeadCountThenLoader[Q](), NoteAudio: buildNoteAudioCountThenLoader[Q](), NoteImage: buildNoteImageCountThenLoader[Q](), Organization: buildOrganizationCountThenLoader[Q](), diff --git a/db/models/bob_joins.bob.go b/db/models/bob_joins.bob.go index 19138466..6e807d2c 100644 --- a/db/models/bob_joins.bob.go +++ b/db/models/bob_joins.bob.go @@ -88,6 +88,7 @@ type joins[Q dialect.Joinable] struct { FileuploadFiles joinSet[fileuploadFileJoins[Q]] FileuploadPools joinSet[fileuploadPoolJoins[Q]] H3Aggregations joinSet[h3AggregationJoins[Q]] + Leads joinSet[leadJoins[Q]] NoteAudios joinSet[noteAudioJoins[Q]] NoteAudioBreadcrumbs joinSet[noteAudioBreadcrumbJoins[Q]] NoteAudioData joinSet[noteAudioDatumJoins[Q]] @@ -185,6 +186,7 @@ func getJoins[Q dialect.Joinable]() joins[Q] { FileuploadFiles: buildJoinSet[fileuploadFileJoins[Q]](FileuploadFiles.Columns, buildFileuploadFileJoins), FileuploadPools: buildJoinSet[fileuploadPoolJoins[Q]](FileuploadPools.Columns, buildFileuploadPoolJoins), H3Aggregations: buildJoinSet[h3AggregationJoins[Q]](H3Aggregations.Columns, buildH3AggregationJoins), + Leads: buildJoinSet[leadJoins[Q]](Leads.Columns, buildLeadJoins), NoteAudios: buildJoinSet[noteAudioJoins[Q]](NoteAudios.Columns, buildNoteAudioJoins), NoteAudioBreadcrumbs: buildJoinSet[noteAudioBreadcrumbJoins[Q]](NoteAudioBreadcrumbs.Columns, buildNoteAudioBreadcrumbJoins), NoteAudioData: buildJoinSet[noteAudioDatumJoins[Q]](NoteAudioData.Columns, buildNoteAudioDatumJoins), diff --git a/db/models/bob_loaders.bob.go b/db/models/bob_loaders.bob.go index 402cb32c..fd842564 100644 --- a/db/models/bob_loaders.bob.go +++ b/db/models/bob_loaders.bob.go @@ -73,6 +73,7 @@ type preloaders struct { FileuploadFile fileuploadFilePreloader FileuploadPool fileuploadPoolPreloader H3Aggregation h3AggregationPreloader + Lead leadPreloader NoteAudio noteAudioPreloader NoteAudioBreadcrumb noteAudioBreadcrumbPreloader NoteAudioDatum noteAudioDatumPreloader @@ -162,6 +163,7 @@ func getPreloaders() preloaders { FileuploadFile: buildFileuploadFilePreloader(), FileuploadPool: buildFileuploadPoolPreloader(), H3Aggregation: buildH3AggregationPreloader(), + Lead: buildLeadPreloader(), NoteAudio: buildNoteAudioPreloader(), NoteAudioBreadcrumb: buildNoteAudioBreadcrumbPreloader(), NoteAudioDatum: buildNoteAudioDatumPreloader(), @@ -257,6 +259,7 @@ type thenLoaders[Q orm.Loadable] struct { FileuploadFile fileuploadFileThenLoader[Q] FileuploadPool fileuploadPoolThenLoader[Q] H3Aggregation h3AggregationThenLoader[Q] + Lead leadThenLoader[Q] NoteAudio noteAudioThenLoader[Q] NoteAudioBreadcrumb noteAudioBreadcrumbThenLoader[Q] NoteAudioDatum noteAudioDatumThenLoader[Q] @@ -346,6 +349,7 @@ func getThenLoaders[Q orm.Loadable]() thenLoaders[Q] { FileuploadFile: buildFileuploadFileThenLoader[Q](), FileuploadPool: buildFileuploadPoolThenLoader[Q](), H3Aggregation: buildH3AggregationThenLoader[Q](), + Lead: buildLeadThenLoader[Q](), NoteAudio: buildNoteAudioThenLoader[Q](), NoteAudioBreadcrumb: buildNoteAudioBreadcrumbThenLoader[Q](), NoteAudioDatum: buildNoteAudioDatumThenLoader[Q](), diff --git a/db/models/bob_where.bob.go b/db/models/bob_where.bob.go index 020719a4..ee3a63bf 100644 --- a/db/models/bob_where.bob.go +++ b/db/models/bob_where.bob.go @@ -76,6 +76,7 @@ func Where[Q psql.Filterable]() struct { GeometryColumns geometryColumnWhere[Q] GooseDBVersions gooseDBVersionWhere[Q] H3Aggregations h3AggregationWhere[Q] + Leads leadWhere[Q] NoteAudios noteAudioWhere[Q] NoteAudioBreadcrumbs noteAudioBreadcrumbWhere[Q] NoteAudioData noteAudioDatumWhere[Q] @@ -171,6 +172,7 @@ func Where[Q psql.Filterable]() struct { GeometryColumns geometryColumnWhere[Q] GooseDBVersions gooseDBVersionWhere[Q] H3Aggregations h3AggregationWhere[Q] + Leads leadWhere[Q] NoteAudios noteAudioWhere[Q] NoteAudioBreadcrumbs noteAudioBreadcrumbWhere[Q] NoteAudioData noteAudioDatumWhere[Q] @@ -265,6 +267,7 @@ func Where[Q psql.Filterable]() struct { GeometryColumns: buildGeometryColumnWhere[Q](GeometryColumns.Columns), GooseDBVersions: buildGooseDBVersionWhere[Q](GooseDBVersions.Columns), H3Aggregations: buildH3AggregationWhere[Q](H3Aggregations.Columns), + Leads: buildLeadWhere[Q](Leads.Columns), NoteAudios: buildNoteAudioWhere[Q](NoteAudios.Columns), NoteAudioBreadcrumbs: buildNoteAudioBreadcrumbWhere[Q](NoteAudioBreadcrumbs.Columns), NoteAudioData: buildNoteAudioDatumWhere[Q](NoteAudioData.Columns), diff --git a/db/models/compliance_report_request.bob.go b/db/models/compliance_report_request.bob.go index fc023f24..9c319da7 100644 --- a/db/models/compliance_report_request.bob.go +++ b/db/models/compliance_report_request.bob.go @@ -20,18 +20,19 @@ import ( "github.com/Gleipnir-Technology/bob/mods" "github.com/Gleipnir-Technology/bob/orm" "github.com/Gleipnir-Technology/bob/types/pgtypes" + "github.com/aarondl/opt/null" "github.com/aarondl/opt/omit" + "github.com/aarondl/opt/omitnull" "github.com/stephenafamo/scan" ) // ComplianceReportRequest is an object representing the database table. type ComplianceReportRequest struct { - Created time.Time `db:"created" ` - Creator int32 `db:"creator" ` - ID int32 `db:"id,pk" ` - PublicID string `db:"public_id" ` - SiteID int32 `db:"site_id" ` - SiteVersion int32 `db:"site_version" ` + Created time.Time `db:"created" ` + Creator int32 `db:"creator" ` + ID int32 `db:"id,pk" ` + PublicID string `db:"public_id" ` + LeadID null.Val[int32] `db:"lead_id" ` R complianceReportRequestR `db:"-" ` @@ -51,34 +52,32 @@ type ComplianceReportRequestsQuery = *psql.ViewQuery[*ComplianceReportRequest, C // complianceReportRequestR is where relationships are stored. type complianceReportRequestR struct { CreatorUser *User // compliance_report_request.compliance_report_request_creator_fkey - Site *Site // compliance_report_request.compliance_report_request_site_id_site_version_fkey + Lead *Lead // compliance_report_request.compliance_report_request_lead_id_fkey Mailers CommsMailerSlice // compliance_report_request_mailer.compliance_report_request_mai_compliance_report_request_id_fkeycompliance_report_request_mailer.compliance_report_request_mailer_mailer_id_fkey } func buildComplianceReportRequestColumns(alias string) complianceReportRequestColumns { return complianceReportRequestColumns{ ColumnsExpr: expr.NewColumnsExpr( - "created", "creator", "id", "public_id", "site_id", "site_version", + "created", "creator", "id", "public_id", "lead_id", ).WithParent("compliance_report_request"), - tableAlias: alias, - Created: psql.Quote(alias, "created"), - Creator: psql.Quote(alias, "creator"), - ID: psql.Quote(alias, "id"), - PublicID: psql.Quote(alias, "public_id"), - SiteID: psql.Quote(alias, "site_id"), - SiteVersion: psql.Quote(alias, "site_version"), + tableAlias: alias, + Created: psql.Quote(alias, "created"), + Creator: psql.Quote(alias, "creator"), + ID: psql.Quote(alias, "id"), + PublicID: psql.Quote(alias, "public_id"), + LeadID: psql.Quote(alias, "lead_id"), } } type complianceReportRequestColumns struct { expr.ColumnsExpr - tableAlias string - Created psql.Expression - Creator psql.Expression - ID psql.Expression - PublicID psql.Expression - SiteID psql.Expression - SiteVersion psql.Expression + tableAlias string + Created psql.Expression + Creator psql.Expression + ID psql.Expression + PublicID psql.Expression + LeadID psql.Expression } func (c complianceReportRequestColumns) Alias() string { @@ -93,16 +92,15 @@ func (complianceReportRequestColumns) AliasedAs(alias string) complianceReportRe // All values are optional, and do not have to be set // Generated columns are not included type ComplianceReportRequestSetter struct { - Created omit.Val[time.Time] `db:"created" ` - Creator omit.Val[int32] `db:"creator" ` - ID omit.Val[int32] `db:"id,pk" ` - PublicID omit.Val[string] `db:"public_id" ` - SiteID omit.Val[int32] `db:"site_id" ` - SiteVersion omit.Val[int32] `db:"site_version" ` + Created omit.Val[time.Time] `db:"created" ` + Creator omit.Val[int32] `db:"creator" ` + ID omit.Val[int32] `db:"id,pk" ` + PublicID omit.Val[string] `db:"public_id" ` + LeadID omitnull.Val[int32] `db:"lead_id" ` } func (s ComplianceReportRequestSetter) SetColumns() []string { - vals := make([]string, 0, 6) + vals := make([]string, 0, 5) if s.Created.IsValue() { vals = append(vals, "created") } @@ -115,11 +113,8 @@ func (s ComplianceReportRequestSetter) SetColumns() []string { if s.PublicID.IsValue() { vals = append(vals, "public_id") } - if s.SiteID.IsValue() { - vals = append(vals, "site_id") - } - if s.SiteVersion.IsValue() { - vals = append(vals, "site_version") + if !s.LeadID.IsUnset() { + vals = append(vals, "lead_id") } return vals } @@ -137,11 +132,8 @@ func (s ComplianceReportRequestSetter) Overwrite(t *ComplianceReportRequest) { if s.PublicID.IsValue() { t.PublicID = s.PublicID.MustGet() } - if s.SiteID.IsValue() { - t.SiteID = s.SiteID.MustGet() - } - if s.SiteVersion.IsValue() { - t.SiteVersion = s.SiteVersion.MustGet() + if !s.LeadID.IsUnset() { + t.LeadID = s.LeadID.MustGetNull() } } @@ -151,7 +143,7 @@ func (s *ComplianceReportRequestSetter) Apply(q *dialect.InsertQuery) { }) q.AppendValues(bob.ExpressionFunc(func(ctx context.Context, w io.StringWriter, d bob.Dialect, start int) ([]any, error) { - vals := make([]bob.Expression, 6) + vals := make([]bob.Expression, 5) if s.Created.IsValue() { vals[0] = psql.Arg(s.Created.MustGet()) } else { @@ -176,18 +168,12 @@ func (s *ComplianceReportRequestSetter) Apply(q *dialect.InsertQuery) { vals[3] = psql.Raw("DEFAULT") } - if s.SiteID.IsValue() { - vals[4] = psql.Arg(s.SiteID.MustGet()) + if !s.LeadID.IsUnset() { + vals[4] = psql.Arg(s.LeadID.MustGetNull()) } else { vals[4] = psql.Raw("DEFAULT") } - if s.SiteVersion.IsValue() { - vals[5] = psql.Arg(s.SiteVersion.MustGet()) - } else { - vals[5] = psql.Raw("DEFAULT") - } - return bob.ExpressSlice(ctx, w, d, start, vals, "", ", ", "") })) } @@ -197,7 +183,7 @@ func (s ComplianceReportRequestSetter) UpdateMod() bob.Mod[*dialect.UpdateQuery] } func (s ComplianceReportRequestSetter) Expressions(prefix ...string) []bob.Expression { - exprs := make([]bob.Expression, 0, 6) + exprs := make([]bob.Expression, 0, 5) if s.Created.IsValue() { exprs = append(exprs, expr.Join{Sep: " = ", Exprs: []bob.Expression{ @@ -227,17 +213,10 @@ func (s ComplianceReportRequestSetter) Expressions(prefix ...string) []bob.Expre }}) } - if s.SiteID.IsValue() { + if !s.LeadID.IsUnset() { exprs = append(exprs, expr.Join{Sep: " = ", Exprs: []bob.Expression{ - psql.Quote(append(prefix, "site_id")...), - psql.Arg(s.SiteID), - }}) - } - - if s.SiteVersion.IsValue() { - exprs = append(exprs, expr.Join{Sep: " = ", Exprs: []bob.Expression{ - psql.Quote(append(prefix, "site_version")...), - psql.Arg(s.SiteVersion), + psql.Quote(append(prefix, "lead_id")...), + psql.Arg(s.LeadID), }}) } @@ -491,31 +470,27 @@ func (os ComplianceReportRequestSlice) CreatorUser(mods ...bob.Mod[*dialect.Sele )...) } -// Site starts a query for related objects on site -func (o *ComplianceReportRequest) Site(mods ...bob.Mod[*dialect.SelectQuery]) SitesQuery { - return Sites.Query(append(mods, - sm.Where(Sites.Columns.ID.EQ(psql.Arg(o.SiteID))), sm.Where(Sites.Columns.Version.EQ(psql.Arg(o.SiteVersion))), +// Lead starts a query for related objects on lead +func (o *ComplianceReportRequest) Lead(mods ...bob.Mod[*dialect.SelectQuery]) LeadsQuery { + return Leads.Query(append(mods, + sm.Where(Leads.Columns.ID.EQ(psql.Arg(o.LeadID))), )...) } -func (os ComplianceReportRequestSlice) Site(mods ...bob.Mod[*dialect.SelectQuery]) SitesQuery { - pkSiteID := make(pgtypes.Array[int32], 0, len(os)) - - pkSiteVersion := make(pgtypes.Array[int32], 0, len(os)) +func (os ComplianceReportRequestSlice) Lead(mods ...bob.Mod[*dialect.SelectQuery]) LeadsQuery { + pkLeadID := make(pgtypes.Array[null.Val[int32]], 0, len(os)) for _, o := range os { if o == nil { continue } - pkSiteID = append(pkSiteID, o.SiteID) - pkSiteVersion = append(pkSiteVersion, o.SiteVersion) + pkLeadID = append(pkLeadID, o.LeadID) } PKArgExpr := psql.Select(sm.Columns( - psql.F("unnest", psql.Cast(psql.Arg(pkSiteID), "integer[]")), - psql.F("unnest", psql.Cast(psql.Arg(pkSiteVersion), "integer[]")), + psql.F("unnest", psql.Cast(psql.Arg(pkLeadID), "integer[]")), )) - return Sites.Query(append(mods, - sm.Where(psql.Group(Sites.Columns.ID, Sites.Columns.Version).OP("IN", PKArgExpr)), + return Leads.Query(append(mods, + sm.Where(psql.Group(Leads.Columns.ID).OP("IN", PKArgExpr)), )...) } @@ -596,62 +571,60 @@ func (complianceReportRequest0 *ComplianceReportRequest) AttachCreatorUser(ctx c return nil } -func attachComplianceReportRequestSite0(ctx context.Context, exec bob.Executor, count int, complianceReportRequest0 *ComplianceReportRequest, site1 *Site) (*ComplianceReportRequest, error) { +func attachComplianceReportRequestLead0(ctx context.Context, exec bob.Executor, count int, complianceReportRequest0 *ComplianceReportRequest, lead1 *Lead) (*ComplianceReportRequest, error) { setter := &ComplianceReportRequestSetter{ - SiteID: omit.From(site1.ID), - SiteVersion: omit.From(site1.Version), + LeadID: omitnull.From(lead1.ID), } err := complianceReportRequest0.Update(ctx, exec, setter) if err != nil { - return nil, fmt.Errorf("attachComplianceReportRequestSite0: %w", err) + return nil, fmt.Errorf("attachComplianceReportRequestLead0: %w", err) } return complianceReportRequest0, nil } -func (complianceReportRequest0 *ComplianceReportRequest) InsertSite(ctx context.Context, exec bob.Executor, related *SiteSetter) error { +func (complianceReportRequest0 *ComplianceReportRequest) InsertLead(ctx context.Context, exec bob.Executor, related *LeadSetter) error { var err error - site1, err := Sites.Insert(related).One(ctx, exec) + lead1, err := Leads.Insert(related).One(ctx, exec) if err != nil { return fmt.Errorf("inserting related objects: %w", err) } - _, err = attachComplianceReportRequestSite0(ctx, exec, 1, complianceReportRequest0, site1) + _, err = attachComplianceReportRequestLead0(ctx, exec, 1, complianceReportRequest0, lead1) if err != nil { return err } - complianceReportRequest0.R.Site = site1 + complianceReportRequest0.R.Lead = lead1 - site1.R.ComplianceReportRequests = append(site1.R.ComplianceReportRequests, complianceReportRequest0) + lead1.R.ComplianceReportRequests = append(lead1.R.ComplianceReportRequests, complianceReportRequest0) return nil } -func (complianceReportRequest0 *ComplianceReportRequest) AttachSite(ctx context.Context, exec bob.Executor, site1 *Site) error { +func (complianceReportRequest0 *ComplianceReportRequest) AttachLead(ctx context.Context, exec bob.Executor, lead1 *Lead) error { var err error - _, err = attachComplianceReportRequestSite0(ctx, exec, 1, complianceReportRequest0, site1) + _, err = attachComplianceReportRequestLead0(ctx, exec, 1, complianceReportRequest0, lead1) if err != nil { return err } - complianceReportRequest0.R.Site = site1 + complianceReportRequest0.R.Lead = lead1 - site1.R.ComplianceReportRequests = append(site1.R.ComplianceReportRequests, complianceReportRequest0) + lead1.R.ComplianceReportRequests = append(lead1.R.ComplianceReportRequests, complianceReportRequest0) return nil } type complianceReportRequestWhere[Q psql.Filterable] struct { - Created psql.WhereMod[Q, time.Time] - Creator psql.WhereMod[Q, int32] - ID psql.WhereMod[Q, int32] - PublicID psql.WhereMod[Q, string] - SiteID psql.WhereMod[Q, int32] - SiteVersion psql.WhereMod[Q, int32] + Created psql.WhereMod[Q, time.Time] + Creator psql.WhereMod[Q, int32] + ID psql.WhereMod[Q, int32] + PublicID psql.WhereMod[Q, string] + LeadID psql.WhereNullMod[Q, int32] } func (complianceReportRequestWhere[Q]) AliasedAs(alias string) complianceReportRequestWhere[Q] { @@ -660,12 +633,11 @@ func (complianceReportRequestWhere[Q]) AliasedAs(alias string) complianceReportR func buildComplianceReportRequestWhere[Q psql.Filterable](cols complianceReportRequestColumns) complianceReportRequestWhere[Q] { return complianceReportRequestWhere[Q]{ - Created: psql.Where[Q, time.Time](cols.Created), - Creator: psql.Where[Q, int32](cols.Creator), - ID: psql.Where[Q, int32](cols.ID), - PublicID: psql.Where[Q, string](cols.PublicID), - SiteID: psql.Where[Q, int32](cols.SiteID), - SiteVersion: psql.Where[Q, int32](cols.SiteVersion), + Created: psql.Where[Q, time.Time](cols.Created), + Creator: psql.Where[Q, int32](cols.Creator), + ID: psql.Where[Q, int32](cols.ID), + PublicID: psql.Where[Q, string](cols.PublicID), + LeadID: psql.WhereNull[Q, int32](cols.LeadID), } } @@ -687,13 +659,13 @@ func (o *ComplianceReportRequest) Preload(name string, retrieved any) error { rel.R.CreatorComplianceReportRequests = ComplianceReportRequestSlice{o} } return nil - case "Site": - rel, ok := retrieved.(*Site) + case "Lead": + rel, ok := retrieved.(*Lead) if !ok { return fmt.Errorf("complianceReportRequest cannot load %T as %q", retrieved, name) } - o.R.Site = rel + o.R.Lead = rel if rel != nil { rel.R.ComplianceReportRequests = ComplianceReportRequestSlice{o} @@ -720,7 +692,7 @@ func (o *ComplianceReportRequest) Preload(name string, retrieved any) error { type complianceReportRequestPreloader struct { CreatorUser func(...psql.PreloadOption) psql.Preloader - Site func(...psql.PreloadOption) psql.Preloader + Lead func(...psql.PreloadOption) psql.Preloader } func buildComplianceReportRequestPreloader() complianceReportRequestPreloader { @@ -738,25 +710,25 @@ func buildComplianceReportRequestPreloader() complianceReportRequestPreloader { }, }, Users.Columns.Names(), opts...) }, - Site: func(opts ...psql.PreloadOption) psql.Preloader { - return psql.Preload[*Site, SiteSlice](psql.PreloadRel{ - Name: "Site", + Lead: func(opts ...psql.PreloadOption) psql.Preloader { + return psql.Preload[*Lead, LeadSlice](psql.PreloadRel{ + Name: "Lead", Sides: []psql.PreloadSide{ { From: ComplianceReportRequests, - To: Sites, - FromColumns: []string{"site_id", "site_version"}, - ToColumns: []string{"id", "version"}, + To: Leads, + FromColumns: []string{"lead_id"}, + ToColumns: []string{"id"}, }, }, - }, Sites.Columns.Names(), opts...) + }, Leads.Columns.Names(), opts...) }, } } type complianceReportRequestThenLoader[Q orm.Loadable] struct { CreatorUser func(...bob.Mod[*dialect.SelectQuery]) orm.Loader[Q] - Site func(...bob.Mod[*dialect.SelectQuery]) orm.Loader[Q] + Lead func(...bob.Mod[*dialect.SelectQuery]) orm.Loader[Q] Mailers func(...bob.Mod[*dialect.SelectQuery]) orm.Loader[Q] } @@ -764,8 +736,8 @@ func buildComplianceReportRequestThenLoader[Q orm.Loadable]() complianceReportRe type CreatorUserLoadInterface interface { LoadCreatorUser(context.Context, bob.Executor, ...bob.Mod[*dialect.SelectQuery]) error } - type SiteLoadInterface interface { - LoadSite(context.Context, bob.Executor, ...bob.Mod[*dialect.SelectQuery]) error + type LeadLoadInterface interface { + LoadLead(context.Context, bob.Executor, ...bob.Mod[*dialect.SelectQuery]) error } type MailersLoadInterface interface { LoadMailers(context.Context, bob.Executor, ...bob.Mod[*dialect.SelectQuery]) error @@ -778,10 +750,10 @@ func buildComplianceReportRequestThenLoader[Q orm.Loadable]() complianceReportRe return retrieved.LoadCreatorUser(ctx, exec, mods...) }, ), - Site: thenLoadBuilder[Q]( - "Site", - func(ctx context.Context, exec bob.Executor, retrieved SiteLoadInterface, mods ...bob.Mod[*dialect.SelectQuery]) error { - return retrieved.LoadSite(ctx, exec, mods...) + Lead: thenLoadBuilder[Q]( + "Lead", + func(ctx context.Context, exec bob.Executor, retrieved LeadLoadInterface, mods ...bob.Mod[*dialect.SelectQuery]) error { + return retrieved.LoadLead(ctx, exec, mods...) }, ), Mailers: thenLoadBuilder[Q]( @@ -845,33 +817,33 @@ func (os ComplianceReportRequestSlice) LoadCreatorUser(ctx context.Context, exec return nil } -// LoadSite loads the complianceReportRequest's Site into the .R struct -func (o *ComplianceReportRequest) LoadSite(ctx context.Context, exec bob.Executor, mods ...bob.Mod[*dialect.SelectQuery]) error { +// LoadLead loads the complianceReportRequest's Lead into the .R struct +func (o *ComplianceReportRequest) LoadLead(ctx context.Context, exec bob.Executor, mods ...bob.Mod[*dialect.SelectQuery]) error { if o == nil { return nil } // Reset the relationship - o.R.Site = nil + o.R.Lead = nil - related, err := o.Site(mods...).One(ctx, exec) + related, err := o.Lead(mods...).One(ctx, exec) if err != nil { return err } related.R.ComplianceReportRequests = ComplianceReportRequestSlice{o} - o.R.Site = related + o.R.Lead = related return nil } -// LoadSite loads the complianceReportRequest's Site into the .R struct -func (os ComplianceReportRequestSlice) LoadSite(ctx context.Context, exec bob.Executor, mods ...bob.Mod[*dialect.SelectQuery]) error { +// LoadLead loads the complianceReportRequest's Lead into the .R struct +func (os ComplianceReportRequestSlice) LoadLead(ctx context.Context, exec bob.Executor, mods ...bob.Mod[*dialect.SelectQuery]) error { if len(os) == 0 { return nil } - sites, err := os.Site(mods...).All(ctx, exec) + leads, err := os.Lead(mods...).All(ctx, exec) if err != nil { return err } @@ -881,19 +853,18 @@ func (os ComplianceReportRequestSlice) LoadSite(ctx context.Context, exec bob.Ex continue } - for _, rel := range sites { - - if !(o.SiteID == rel.ID) { + for _, rel := range leads { + if !o.LeadID.IsValue() { continue } - if !(o.SiteVersion == rel.Version) { + if !(o.LeadID.IsValue() && o.LeadID.MustGet() == rel.ID) { continue } rel.R.ComplianceReportRequests = append(rel.R.ComplianceReportRequests, o) - o.R.Site = rel + o.R.Lead = rel break } } @@ -1081,7 +1052,7 @@ func (os ComplianceReportRequestSlice) LoadCountMailers(ctx context.Context, exe type complianceReportRequestJoins[Q dialect.Joinable] struct { typ string CreatorUser modAs[Q, userColumns] - Site modAs[Q, siteColumns] + Lead modAs[Q, leadColumns] Mailers modAs[Q, commsMailerColumns] } @@ -1106,14 +1077,14 @@ func buildComplianceReportRequestJoins[Q dialect.Joinable](cols complianceReport return mods }, }, - Site: modAs[Q, siteColumns]{ - c: Sites.Columns, - f: func(to siteColumns) bob.Mod[Q] { + Lead: modAs[Q, leadColumns]{ + c: Leads.Columns, + f: func(to leadColumns) bob.Mod[Q] { mods := make(mods.QueryMods[Q], 0, 1) { - mods = append(mods, dialect.Join[Q](typ, Sites.Name().As(to.Alias())).On( - to.ID.EQ(cols.SiteID), to.Version.EQ(cols.SiteVersion), + mods = append(mods, dialect.Join[Q](typ, Leads.Name().As(to.Alias())).On( + to.ID.EQ(cols.LeadID), )) } diff --git a/db/models/fileupload.file.bob.go b/db/models/fileupload.file.bob.go index 91b9b39f..ebb42ee4 100644 --- a/db/models/fileupload.file.bob.go +++ b/db/models/fileupload.file.bob.go @@ -38,6 +38,7 @@ type FileuploadFile struct { Status enums.FileuploadFilestatustype `db:"status" ` SizeBytes int32 `db:"size_bytes" ` FileUUID uuid.UUID `db:"file_uuid" ` + Committer null.Val[int32] `db:"committer" ` R fileuploadFileR `db:"-" ` @@ -56,17 +57,18 @@ type FileuploadFilesQuery = *psql.ViewQuery[*FileuploadFile, FileuploadFileSlice // fileuploadFileR is where relationships are stored. type fileuploadFileR struct { - CSV *FileuploadCSV // fileupload.csv.csv_file_id_fkey - ErrorFiles FileuploadErrorFileSlice // fileupload.error_file.error_file_file_id_fkey - CreatorUser *User // fileupload.file.file_creator_id_fkey - Organization *Organization // fileupload.file.file_organization_id_fkey - Sites SiteSlice // site.site_file_id_fkey + CSV *FileuploadCSV // fileupload.csv.csv_file_id_fkey + ErrorFiles FileuploadErrorFileSlice // fileupload.error_file.error_file_file_id_fkey + CommitterUser *User // fileupload.file.file_committer_fkey + CreatorUser *User // fileupload.file.file_creator_id_fkey + Organization *Organization // fileupload.file.file_organization_id_fkey + Sites SiteSlice // site.site_file_id_fkey } func buildFileuploadFileColumns(alias string) fileuploadFileColumns { return fileuploadFileColumns{ ColumnsExpr: expr.NewColumnsExpr( - "id", "content_type", "created", "creator_id", "deleted", "name", "organization_id", "status", "size_bytes", "file_uuid", + "id", "content_type", "created", "creator_id", "deleted", "name", "organization_id", "status", "size_bytes", "file_uuid", "committer", ).WithParent("fileupload.file"), tableAlias: alias, ID: psql.Quote(alias, "id"), @@ -79,6 +81,7 @@ func buildFileuploadFileColumns(alias string) fileuploadFileColumns { Status: psql.Quote(alias, "status"), SizeBytes: psql.Quote(alias, "size_bytes"), FileUUID: psql.Quote(alias, "file_uuid"), + Committer: psql.Quote(alias, "committer"), } } @@ -95,6 +98,7 @@ type fileuploadFileColumns struct { Status psql.Expression SizeBytes psql.Expression FileUUID psql.Expression + Committer psql.Expression } func (c fileuploadFileColumns) Alias() string { @@ -119,10 +123,11 @@ type FileuploadFileSetter struct { Status omit.Val[enums.FileuploadFilestatustype] `db:"status" ` SizeBytes omit.Val[int32] `db:"size_bytes" ` FileUUID omit.Val[uuid.UUID] `db:"file_uuid" ` + Committer omitnull.Val[int32] `db:"committer" ` } func (s FileuploadFileSetter) SetColumns() []string { - vals := make([]string, 0, 10) + vals := make([]string, 0, 11) if s.ID.IsValue() { vals = append(vals, "id") } @@ -153,6 +158,9 @@ func (s FileuploadFileSetter) SetColumns() []string { if s.FileUUID.IsValue() { vals = append(vals, "file_uuid") } + if !s.Committer.IsUnset() { + vals = append(vals, "committer") + } return vals } @@ -187,6 +195,9 @@ func (s FileuploadFileSetter) Overwrite(t *FileuploadFile) { if s.FileUUID.IsValue() { t.FileUUID = s.FileUUID.MustGet() } + if !s.Committer.IsUnset() { + t.Committer = s.Committer.MustGetNull() + } } func (s *FileuploadFileSetter) Apply(q *dialect.InsertQuery) { @@ -195,7 +206,7 @@ func (s *FileuploadFileSetter) Apply(q *dialect.InsertQuery) { }) q.AppendValues(bob.ExpressionFunc(func(ctx context.Context, w io.StringWriter, d bob.Dialect, start int) ([]any, error) { - vals := make([]bob.Expression, 10) + vals := make([]bob.Expression, 11) if s.ID.IsValue() { vals[0] = psql.Arg(s.ID.MustGet()) } else { @@ -256,6 +267,12 @@ func (s *FileuploadFileSetter) Apply(q *dialect.InsertQuery) { vals[9] = psql.Raw("DEFAULT") } + if !s.Committer.IsUnset() { + vals[10] = psql.Arg(s.Committer.MustGetNull()) + } else { + vals[10] = psql.Raw("DEFAULT") + } + return bob.ExpressSlice(ctx, w, d, start, vals, "", ", ", "") })) } @@ -265,7 +282,7 @@ func (s FileuploadFileSetter) UpdateMod() bob.Mod[*dialect.UpdateQuery] { } func (s FileuploadFileSetter) Expressions(prefix ...string) []bob.Expression { - exprs := make([]bob.Expression, 0, 10) + exprs := make([]bob.Expression, 0, 11) if s.ID.IsValue() { exprs = append(exprs, expr.Join{Sep: " = ", Exprs: []bob.Expression{ @@ -337,6 +354,13 @@ func (s FileuploadFileSetter) Expressions(prefix ...string) []bob.Expression { }}) } + if !s.Committer.IsUnset() { + exprs = append(exprs, expr.Join{Sep: " = ", Exprs: []bob.Expression{ + psql.Quote(append(prefix, "committer")...), + psql.Arg(s.Committer), + }}) + } + return exprs } @@ -611,6 +635,30 @@ func (os FileuploadFileSlice) ErrorFiles(mods ...bob.Mod[*dialect.SelectQuery]) )...) } +// CommitterUser starts a query for related objects on user_ +func (o *FileuploadFile) CommitterUser(mods ...bob.Mod[*dialect.SelectQuery]) UsersQuery { + return Users.Query(append(mods, + sm.Where(Users.Columns.ID.EQ(psql.Arg(o.Committer))), + )...) +} + +func (os FileuploadFileSlice) CommitterUser(mods ...bob.Mod[*dialect.SelectQuery]) UsersQuery { + pkCommitter := make(pgtypes.Array[null.Val[int32]], 0, len(os)) + for _, o := range os { + if o == nil { + continue + } + pkCommitter = append(pkCommitter, o.Committer) + } + PKArgExpr := psql.Select(sm.Columns( + psql.F("unnest", psql.Cast(psql.Arg(pkCommitter), "integer[]")), + )) + + return Users.Query(append(mods, + sm.Where(psql.Group(Users.Columns.ID).OP("IN", PKArgExpr)), + )...) +} + // CreatorUser starts a query for related objects on user_ func (o *FileuploadFile) CreatorUser(mods ...bob.Mod[*dialect.SelectQuery]) UsersQuery { return Users.Query(append(mods, @@ -805,6 +853,54 @@ func (fileuploadFile0 *FileuploadFile) AttachErrorFiles(ctx context.Context, exe return nil } +func attachFileuploadFileCommitterUser0(ctx context.Context, exec bob.Executor, count int, fileuploadFile0 *FileuploadFile, user1 *User) (*FileuploadFile, error) { + setter := &FileuploadFileSetter{ + Committer: omitnull.From(user1.ID), + } + + err := fileuploadFile0.Update(ctx, exec, setter) + if err != nil { + return nil, fmt.Errorf("attachFileuploadFileCommitterUser0: %w", err) + } + + return fileuploadFile0, nil +} + +func (fileuploadFile0 *FileuploadFile) InsertCommitterUser(ctx context.Context, exec bob.Executor, related *UserSetter) error { + var err error + + user1, err := Users.Insert(related).One(ctx, exec) + if err != nil { + return fmt.Errorf("inserting related objects: %w", err) + } + + _, err = attachFileuploadFileCommitterUser0(ctx, exec, 1, fileuploadFile0, user1) + if err != nil { + return err + } + + fileuploadFile0.R.CommitterUser = user1 + + user1.R.CommitterFiles = append(user1.R.CommitterFiles, fileuploadFile0) + + return nil +} + +func (fileuploadFile0 *FileuploadFile) AttachCommitterUser(ctx context.Context, exec bob.Executor, user1 *User) error { + var err error + + _, err = attachFileuploadFileCommitterUser0(ctx, exec, 1, fileuploadFile0, user1) + if err != nil { + return err + } + + fileuploadFile0.R.CommitterUser = user1 + + user1.R.CommitterFiles = append(user1.R.CommitterFiles, fileuploadFile0) + + return nil +} + func attachFileuploadFileCreatorUser0(ctx context.Context, exec bob.Executor, count int, fileuploadFile0 *FileuploadFile, user1 *User) (*FileuploadFile, error) { setter := &FileuploadFileSetter{ CreatorID: omit.From(user1.ID), @@ -980,6 +1076,7 @@ type fileuploadFileWhere[Q psql.Filterable] struct { Status psql.WhereMod[Q, enums.FileuploadFilestatustype] SizeBytes psql.WhereMod[Q, int32] FileUUID psql.WhereMod[Q, uuid.UUID] + Committer psql.WhereNullMod[Q, int32] } func (fileuploadFileWhere[Q]) AliasedAs(alias string) fileuploadFileWhere[Q] { @@ -998,6 +1095,7 @@ func buildFileuploadFileWhere[Q psql.Filterable](cols fileuploadFileColumns) fil Status: psql.Where[Q, enums.FileuploadFilestatustype](cols.Status), SizeBytes: psql.Where[Q, int32](cols.SizeBytes), FileUUID: psql.Where[Q, uuid.UUID](cols.FileUUID), + Committer: psql.WhereNull[Q, int32](cols.Committer), } } @@ -1033,6 +1131,18 @@ func (o *FileuploadFile) Preload(name string, retrieved any) error { } } return nil + case "CommitterUser": + rel, ok := retrieved.(*User) + if !ok { + return fmt.Errorf("fileuploadFile cannot load %T as %q", retrieved, name) + } + + o.R.CommitterUser = rel + + if rel != nil { + rel.R.CommitterFiles = FileuploadFileSlice{o} + } + return nil case "CreatorUser": rel, ok := retrieved.(*User) if !ok { @@ -1077,9 +1187,10 @@ func (o *FileuploadFile) Preload(name string, retrieved any) error { } type fileuploadFilePreloader struct { - CSV func(...psql.PreloadOption) psql.Preloader - CreatorUser func(...psql.PreloadOption) psql.Preloader - Organization func(...psql.PreloadOption) psql.Preloader + CSV func(...psql.PreloadOption) psql.Preloader + CommitterUser func(...psql.PreloadOption) psql.Preloader + CreatorUser func(...psql.PreloadOption) psql.Preloader + Organization func(...psql.PreloadOption) psql.Preloader } func buildFileuploadFilePreloader() fileuploadFilePreloader { @@ -1097,6 +1208,19 @@ func buildFileuploadFilePreloader() fileuploadFilePreloader { }, }, FileuploadCSVS.Columns.Names(), opts...) }, + CommitterUser: func(opts ...psql.PreloadOption) psql.Preloader { + return psql.Preload[*User, UserSlice](psql.PreloadRel{ + Name: "CommitterUser", + Sides: []psql.PreloadSide{ + { + From: FileuploadFiles, + To: Users, + FromColumns: []string{"committer"}, + ToColumns: []string{"id"}, + }, + }, + }, Users.Columns.Names(), opts...) + }, CreatorUser: func(opts ...psql.PreloadOption) psql.Preloader { return psql.Preload[*User, UserSlice](psql.PreloadRel{ Name: "CreatorUser", @@ -1127,11 +1251,12 @@ func buildFileuploadFilePreloader() fileuploadFilePreloader { } type fileuploadFileThenLoader[Q orm.Loadable] struct { - CSV func(...bob.Mod[*dialect.SelectQuery]) orm.Loader[Q] - ErrorFiles func(...bob.Mod[*dialect.SelectQuery]) orm.Loader[Q] - CreatorUser func(...bob.Mod[*dialect.SelectQuery]) orm.Loader[Q] - Organization func(...bob.Mod[*dialect.SelectQuery]) orm.Loader[Q] - Sites func(...bob.Mod[*dialect.SelectQuery]) orm.Loader[Q] + CSV func(...bob.Mod[*dialect.SelectQuery]) orm.Loader[Q] + ErrorFiles func(...bob.Mod[*dialect.SelectQuery]) orm.Loader[Q] + CommitterUser func(...bob.Mod[*dialect.SelectQuery]) orm.Loader[Q] + CreatorUser func(...bob.Mod[*dialect.SelectQuery]) orm.Loader[Q] + Organization func(...bob.Mod[*dialect.SelectQuery]) orm.Loader[Q] + Sites func(...bob.Mod[*dialect.SelectQuery]) orm.Loader[Q] } func buildFileuploadFileThenLoader[Q orm.Loadable]() fileuploadFileThenLoader[Q] { @@ -1141,6 +1266,9 @@ func buildFileuploadFileThenLoader[Q orm.Loadable]() fileuploadFileThenLoader[Q] type ErrorFilesLoadInterface interface { LoadErrorFiles(context.Context, bob.Executor, ...bob.Mod[*dialect.SelectQuery]) error } + type CommitterUserLoadInterface interface { + LoadCommitterUser(context.Context, bob.Executor, ...bob.Mod[*dialect.SelectQuery]) error + } type CreatorUserLoadInterface interface { LoadCreatorUser(context.Context, bob.Executor, ...bob.Mod[*dialect.SelectQuery]) error } @@ -1164,6 +1292,12 @@ func buildFileuploadFileThenLoader[Q orm.Loadable]() fileuploadFileThenLoader[Q] return retrieved.LoadErrorFiles(ctx, exec, mods...) }, ), + CommitterUser: thenLoadBuilder[Q]( + "CommitterUser", + func(ctx context.Context, exec bob.Executor, retrieved CommitterUserLoadInterface, mods ...bob.Mod[*dialect.SelectQuery]) error { + return retrieved.LoadCommitterUser(ctx, exec, mods...) + }, + ), CreatorUser: thenLoadBuilder[Q]( "CreatorUser", func(ctx context.Context, exec bob.Executor, retrieved CreatorUserLoadInterface, mods ...bob.Mod[*dialect.SelectQuery]) error { @@ -1298,6 +1432,61 @@ func (os FileuploadFileSlice) LoadErrorFiles(ctx context.Context, exec bob.Execu return nil } +// LoadCommitterUser loads the fileuploadFile's CommitterUser into the .R struct +func (o *FileuploadFile) LoadCommitterUser(ctx context.Context, exec bob.Executor, mods ...bob.Mod[*dialect.SelectQuery]) error { + if o == nil { + return nil + } + + // Reset the relationship + o.R.CommitterUser = nil + + related, err := o.CommitterUser(mods...).One(ctx, exec) + if err != nil { + return err + } + + related.R.CommitterFiles = FileuploadFileSlice{o} + + o.R.CommitterUser = related + return nil +} + +// LoadCommitterUser loads the fileuploadFile's CommitterUser into the .R struct +func (os FileuploadFileSlice) LoadCommitterUser(ctx context.Context, exec bob.Executor, mods ...bob.Mod[*dialect.SelectQuery]) error { + if len(os) == 0 { + return nil + } + + users, err := os.CommitterUser(mods...).All(ctx, exec) + if err != nil { + return err + } + + for _, o := range os { + if o == nil { + continue + } + + for _, rel := range users { + if !o.Committer.IsValue() { + continue + } + + if !(o.Committer.IsValue() && o.Committer.MustGet() == rel.ID) { + continue + } + + rel.R.CommitterFiles = append(rel.R.CommitterFiles, o) + + o.R.CommitterUser = rel + break + } + } + + return nil +} + // LoadCreatorUser loads the fileuploadFile's CreatorUser into the .R struct func (o *FileuploadFile) LoadCreatorUser(ctx context.Context, exec bob.Executor, mods ...bob.Mod[*dialect.SelectQuery]) error { if o == nil { @@ -1621,12 +1810,13 @@ func (os FileuploadFileSlice) LoadCountSites(ctx context.Context, exec bob.Execu } type fileuploadFileJoins[Q dialect.Joinable] struct { - typ string - CSV modAs[Q, fileuploadCSVColumns] - ErrorFiles modAs[Q, fileuploadErrorFileColumns] - CreatorUser modAs[Q, userColumns] - Organization modAs[Q, organizationColumns] - Sites modAs[Q, siteColumns] + typ string + CSV modAs[Q, fileuploadCSVColumns] + ErrorFiles modAs[Q, fileuploadErrorFileColumns] + CommitterUser modAs[Q, userColumns] + CreatorUser modAs[Q, userColumns] + Organization modAs[Q, organizationColumns] + Sites modAs[Q, siteColumns] } func (j fileuploadFileJoins[Q]) aliasedAs(alias string) fileuploadFileJoins[Q] { @@ -1664,6 +1854,20 @@ func buildFileuploadFileJoins[Q dialect.Joinable](cols fileuploadFileColumns, ty return mods }, }, + CommitterUser: modAs[Q, userColumns]{ + c: Users.Columns, + f: func(to userColumns) bob.Mod[Q] { + mods := make(mods.QueryMods[Q], 0, 1) + + { + mods = append(mods, dialect.Join[Q](typ, Users.Name().As(to.Alias())).On( + to.ID.EQ(cols.Committer), + )) + } + + return mods + }, + }, CreatorUser: modAs[Q, userColumns]{ c: Users.Columns, f: func(to userColumns) bob.Mod[Q] { diff --git a/db/models/fileupload.pool.bob.go b/db/models/fileupload.pool.bob.go index 5bc0805e..0f76ccac 100644 --- a/db/models/fileupload.pool.bob.go +++ b/db/models/fileupload.pool.bob.go @@ -27,29 +27,29 @@ import ( // FileuploadPool is an object representing the database table. type FileuploadPool struct { - 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" ` - PropertyOwnerName string `db:"property_owner_name" ` - PropertyOwnerPhoneE164 null.Val[string] `db:"property_owner_phone_e164" ` - ResidentOwned null.Val[bool] `db:"resident_owned" ` - ResidentPhoneE164 null.Val[string] `db:"resident_phone_e164" ` - LineNumber int32 `db:"line_number" ` - Tags pgtypes.HStore `db:"tags" ` - AddressNumber string `db:"address_number" ` - AddressLocality string `db:"address_locality" ` - AddressRegion string `db:"address_region" ` + AddressPostalCode string `db:"address_postal_code" ` + AddressStreet string `db:"address_street" ` + Committed bool `db:"committed" ` + 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" ` + PropertyOwnerName string `db:"property_owner_name" ` + PropertyOwnerPhoneE164 null.Val[string] `db:"property_owner_phone_e164" ` + ResidentOwned null.Val[bool] `db:"resident_owned" ` + ResidentPhoneE164 null.Val[string] `db:"resident_phone_e164" ` + LineNumber int32 `db:"line_number" ` + Tags pgtypes.HStore `db:"tags" ` + AddressNumber string `db:"address_number" ` + AddressLocality string `db:"address_locality" ` + AddressRegion string `db:"address_region" ` + Condition enums.Poolconditiontype `db:"condition" ` R fileuploadPoolR `db:"-" ` } @@ -75,13 +75,12 @@ type fileuploadPoolR struct { func buildFileuploadPoolColumns(alias string) fileuploadPoolColumns { return fileuploadPoolColumns{ ColumnsExpr: expr.NewColumnsExpr( - "address_postal_code", "address_street", "committed", "condition", "created", "creator_id", "csv_file", "deleted", "geom", "h3cell", "id", "is_in_district", "is_new", "notes", "property_owner_name", "property_owner_phone_e164", "resident_owned", "resident_phone_e164", "line_number", "tags", "address_number", "address_locality", "address_region", + "address_postal_code", "address_street", "committed", "created", "creator_id", "csv_file", "deleted", "geom", "h3cell", "id", "is_in_district", "is_new", "notes", "property_owner_name", "property_owner_phone_e164", "resident_owned", "resident_phone_e164", "line_number", "tags", "address_number", "address_locality", "address_region", "condition", ).WithParent("fileupload.pool"), tableAlias: alias, 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"), @@ -101,6 +100,7 @@ func buildFileuploadPoolColumns(alias string) fileuploadPoolColumns { AddressNumber: psql.Quote(alias, "address_number"), AddressLocality: psql.Quote(alias, "address_locality"), AddressRegion: psql.Quote(alias, "address_region"), + Condition: psql.Quote(alias, "condition"), } } @@ -110,7 +110,6 @@ type fileuploadPoolColumns struct { AddressPostalCode psql.Expression AddressStreet psql.Expression Committed psql.Expression - Condition psql.Expression Created psql.Expression CreatorID psql.Expression CSVFile psql.Expression @@ -130,6 +129,7 @@ type fileuploadPoolColumns struct { AddressNumber psql.Expression AddressLocality psql.Expression AddressRegion psql.Expression + Condition psql.Expression } func (c fileuploadPoolColumns) Alias() string { @@ -144,29 +144,29 @@ 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 { - 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" ` - PropertyOwnerName omit.Val[string] `db:"property_owner_name" ` - PropertyOwnerPhoneE164 omitnull.Val[string] `db:"property_owner_phone_e164" ` - ResidentOwned omitnull.Val[bool] `db:"resident_owned" ` - ResidentPhoneE164 omitnull.Val[string] `db:"resident_phone_e164" ` - LineNumber omit.Val[int32] `db:"line_number" ` - Tags omit.Val[pgtypes.HStore] `db:"tags" ` - AddressNumber omit.Val[string] `db:"address_number" ` - AddressLocality omit.Val[string] `db:"address_locality" ` - AddressRegion omit.Val[string] `db:"address_region" ` + AddressPostalCode omit.Val[string] `db:"address_postal_code" ` + AddressStreet omit.Val[string] `db:"address_street" ` + Committed omit.Val[bool] `db:"committed" ` + 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" ` + PropertyOwnerName omit.Val[string] `db:"property_owner_name" ` + PropertyOwnerPhoneE164 omitnull.Val[string] `db:"property_owner_phone_e164" ` + ResidentOwned omitnull.Val[bool] `db:"resident_owned" ` + ResidentPhoneE164 omitnull.Val[string] `db:"resident_phone_e164" ` + LineNumber omit.Val[int32] `db:"line_number" ` + Tags omit.Val[pgtypes.HStore] `db:"tags" ` + AddressNumber omit.Val[string] `db:"address_number" ` + AddressLocality omit.Val[string] `db:"address_locality" ` + AddressRegion omit.Val[string] `db:"address_region" ` + Condition omit.Val[enums.Poolconditiontype] `db:"condition" ` } func (s FileuploadPoolSetter) SetColumns() []string { @@ -180,9 +180,6 @@ func (s FileuploadPoolSetter) SetColumns() []string { if s.Committed.IsValue() { vals = append(vals, "committed") } - if s.Condition.IsValue() { - vals = append(vals, "condition") - } if s.Created.IsValue() { vals = append(vals, "created") } @@ -240,6 +237,9 @@ func (s FileuploadPoolSetter) SetColumns() []string { if s.AddressRegion.IsValue() { vals = append(vals, "address_region") } + if s.Condition.IsValue() { + vals = append(vals, "condition") + } return vals } @@ -253,9 +253,6 @@ func (s FileuploadPoolSetter) Overwrite(t *FileuploadPool) { if s.Committed.IsValue() { t.Committed = s.Committed.MustGet() } - if s.Condition.IsValue() { - t.Condition = s.Condition.MustGet() - } if s.Created.IsValue() { t.Created = s.Created.MustGet() } @@ -313,6 +310,9 @@ func (s FileuploadPoolSetter) Overwrite(t *FileuploadPool) { if s.AddressRegion.IsValue() { t.AddressRegion = s.AddressRegion.MustGet() } + if s.Condition.IsValue() { + t.Condition = s.Condition.MustGet() + } } func (s *FileuploadPoolSetter) Apply(q *dialect.InsertQuery) { @@ -340,122 +340,122 @@ func (s *FileuploadPoolSetter) Apply(q *dialect.InsertQuery) { vals[2] = psql.Raw("DEFAULT") } - if s.Condition.IsValue() { - vals[3] = psql.Arg(s.Condition.MustGet()) + if s.Created.IsValue() { + vals[3] = psql.Arg(s.Created.MustGet()) } else { vals[3] = psql.Raw("DEFAULT") } - if s.Created.IsValue() { - vals[4] = psql.Arg(s.Created.MustGet()) + if s.CreatorID.IsValue() { + vals[4] = psql.Arg(s.CreatorID.MustGet()) } else { vals[4] = psql.Raw("DEFAULT") } - if s.CreatorID.IsValue() { - vals[5] = psql.Arg(s.CreatorID.MustGet()) + if s.CSVFile.IsValue() { + vals[5] = psql.Arg(s.CSVFile.MustGet()) } else { vals[5] = psql.Raw("DEFAULT") } - if s.CSVFile.IsValue() { - vals[6] = psql.Arg(s.CSVFile.MustGet()) + if !s.Deleted.IsUnset() { + vals[6] = psql.Arg(s.Deleted.MustGetNull()) } else { vals[6] = psql.Raw("DEFAULT") } - if !s.Deleted.IsUnset() { - vals[7] = psql.Arg(s.Deleted.MustGetNull()) + if !s.Geom.IsUnset() { + vals[7] = psql.Arg(s.Geom.MustGetNull()) } else { vals[7] = psql.Raw("DEFAULT") } - if !s.Geom.IsUnset() { - vals[8] = psql.Arg(s.Geom.MustGetNull()) + if !s.H3cell.IsUnset() { + vals[8] = psql.Arg(s.H3cell.MustGetNull()) } else { vals[8] = psql.Raw("DEFAULT") } - if !s.H3cell.IsUnset() { - vals[9] = psql.Arg(s.H3cell.MustGetNull()) + if s.ID.IsValue() { + vals[9] = psql.Arg(s.ID.MustGet()) } else { vals[9] = psql.Raw("DEFAULT") } - if s.ID.IsValue() { - vals[10] = psql.Arg(s.ID.MustGet()) + if s.IsInDistrict.IsValue() { + vals[10] = psql.Arg(s.IsInDistrict.MustGet()) } else { vals[10] = psql.Raw("DEFAULT") } - if s.IsInDistrict.IsValue() { - vals[11] = psql.Arg(s.IsInDistrict.MustGet()) + if s.IsNew.IsValue() { + vals[11] = psql.Arg(s.IsNew.MustGet()) } else { vals[11] = psql.Raw("DEFAULT") } - if s.IsNew.IsValue() { - vals[12] = psql.Arg(s.IsNew.MustGet()) + if s.Notes.IsValue() { + vals[12] = psql.Arg(s.Notes.MustGet()) } else { vals[12] = psql.Raw("DEFAULT") } - if s.Notes.IsValue() { - vals[13] = psql.Arg(s.Notes.MustGet()) + if s.PropertyOwnerName.IsValue() { + vals[13] = psql.Arg(s.PropertyOwnerName.MustGet()) } else { vals[13] = psql.Raw("DEFAULT") } - if s.PropertyOwnerName.IsValue() { - vals[14] = psql.Arg(s.PropertyOwnerName.MustGet()) + if !s.PropertyOwnerPhoneE164.IsUnset() { + vals[14] = psql.Arg(s.PropertyOwnerPhoneE164.MustGetNull()) } else { vals[14] = psql.Raw("DEFAULT") } - if !s.PropertyOwnerPhoneE164.IsUnset() { - vals[15] = psql.Arg(s.PropertyOwnerPhoneE164.MustGetNull()) + if !s.ResidentOwned.IsUnset() { + vals[15] = psql.Arg(s.ResidentOwned.MustGetNull()) } else { vals[15] = psql.Raw("DEFAULT") } - if !s.ResidentOwned.IsUnset() { - vals[16] = psql.Arg(s.ResidentOwned.MustGetNull()) + if !s.ResidentPhoneE164.IsUnset() { + vals[16] = psql.Arg(s.ResidentPhoneE164.MustGetNull()) } else { vals[16] = psql.Raw("DEFAULT") } - if !s.ResidentPhoneE164.IsUnset() { - vals[17] = psql.Arg(s.ResidentPhoneE164.MustGetNull()) + if s.LineNumber.IsValue() { + vals[17] = psql.Arg(s.LineNumber.MustGet()) } else { vals[17] = psql.Raw("DEFAULT") } - if s.LineNumber.IsValue() { - vals[18] = psql.Arg(s.LineNumber.MustGet()) + if s.Tags.IsValue() { + vals[18] = psql.Arg(s.Tags.MustGet()) } else { vals[18] = psql.Raw("DEFAULT") } - if s.Tags.IsValue() { - vals[19] = psql.Arg(s.Tags.MustGet()) + if s.AddressNumber.IsValue() { + vals[19] = psql.Arg(s.AddressNumber.MustGet()) } else { vals[19] = psql.Raw("DEFAULT") } - if s.AddressNumber.IsValue() { - vals[20] = psql.Arg(s.AddressNumber.MustGet()) + if s.AddressLocality.IsValue() { + vals[20] = psql.Arg(s.AddressLocality.MustGet()) } else { vals[20] = psql.Raw("DEFAULT") } - if s.AddressLocality.IsValue() { - vals[21] = psql.Arg(s.AddressLocality.MustGet()) + if s.AddressRegion.IsValue() { + vals[21] = psql.Arg(s.AddressRegion.MustGet()) } else { vals[21] = psql.Raw("DEFAULT") } - if s.AddressRegion.IsValue() { - vals[22] = psql.Arg(s.AddressRegion.MustGet()) + if s.Condition.IsValue() { + vals[22] = psql.Arg(s.Condition.MustGet()) } else { vals[22] = psql.Raw("DEFAULT") } @@ -492,13 +492,6 @@ func (s FileuploadPoolSetter) Expressions(prefix ...string) []bob.Expression { }}) } - if s.Condition.IsValue() { - exprs = append(exprs, expr.Join{Sep: " = ", Exprs: []bob.Expression{ - psql.Quote(append(prefix, "condition")...), - psql.Arg(s.Condition), - }}) - } - if s.Created.IsValue() { exprs = append(exprs, expr.Join{Sep: " = ", Exprs: []bob.Expression{ psql.Quote(append(prefix, "created")...), @@ -632,6 +625,13 @@ func (s FileuploadPoolSetter) Expressions(prefix ...string) []bob.Expression { }}) } + if s.Condition.IsValue() { + exprs = append(exprs, expr.Join{Sep: " = ", Exprs: []bob.Expression{ + psql.Quote(append(prefix, "condition")...), + psql.Arg(s.Condition), + }}) + } + return exprs } @@ -1150,7 +1150,6 @@ type fileuploadPoolWhere[Q psql.Filterable] struct { 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] @@ -1170,6 +1169,7 @@ type fileuploadPoolWhere[Q psql.Filterable] struct { AddressNumber psql.WhereMod[Q, string] AddressLocality psql.WhereMod[Q, string] AddressRegion psql.WhereMod[Q, string] + Condition psql.WhereMod[Q, enums.Poolconditiontype] } func (fileuploadPoolWhere[Q]) AliasedAs(alias string) fileuploadPoolWhere[Q] { @@ -1181,7 +1181,6 @@ func buildFileuploadPoolWhere[Q psql.Filterable](cols fileuploadPoolColumns) fil 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), @@ -1201,6 +1200,7 @@ func buildFileuploadPoolWhere[Q psql.Filterable](cols fileuploadPoolColumns) fil AddressNumber: psql.Where[Q, string](cols.AddressNumber), AddressLocality: psql.Where[Q, string](cols.AddressLocality), AddressRegion: psql.Where[Q, string](cols.AddressRegion), + Condition: psql.Where[Q, enums.Poolconditiontype](cols.Condition), } } diff --git a/db/models/lead.bob.go b/db/models/lead.bob.go new file mode 100644 index 00000000..e75cc848 --- /dev/null +++ b/db/models/lead.bob.go @@ -0,0 +1,1389 @@ +// Code generated by BobGen psql v0.42.5. DO NOT EDIT. +// This file is meant to be re-generated in place and/or deleted at any time. + +package models + +import ( + "context" + "fmt" + "io" + "time" + + "github.com/Gleipnir-Technology/bob" + "github.com/Gleipnir-Technology/bob/dialect/psql" + "github.com/Gleipnir-Technology/bob/dialect/psql/dialect" + "github.com/Gleipnir-Technology/bob/dialect/psql/dm" + "github.com/Gleipnir-Technology/bob/dialect/psql/sm" + "github.com/Gleipnir-Technology/bob/dialect/psql/um" + "github.com/Gleipnir-Technology/bob/expr" + "github.com/Gleipnir-Technology/bob/mods" + "github.com/Gleipnir-Technology/bob/orm" + "github.com/Gleipnir-Technology/bob/types/pgtypes" + enums "github.com/Gleipnir-Technology/nidus-sync/db/enums" + "github.com/aarondl/opt/null" + "github.com/aarondl/opt/omit" + "github.com/aarondl/opt/omitnull" +) + +// Lead is an object representing the database table. +type Lead struct { + Created time.Time `db:"created" ` + Creator int32 `db:"creator" ` + ID int32 `db:"id,pk" ` + OrganizationID int32 `db:"organization_id" ` + SiteID null.Val[int32] `db:"site_id" ` + SiteVersion null.Val[int32] `db:"site_version" ` + Type enums.Leadtype `db:"type_" ` + + R leadR `db:"-" ` + + C leadC `db:"-" ` +} + +// LeadSlice is an alias for a slice of pointers to Lead. +// This should almost always be used instead of []*Lead. +type LeadSlice []*Lead + +// Leads contains methods to work with the lead table +var Leads = psql.NewTablex[*Lead, LeadSlice, *LeadSetter]("", "lead", buildLeadColumns("lead")) + +// LeadsQuery is a query on the lead table +type LeadsQuery = *psql.ViewQuery[*Lead, LeadSlice] + +// leadR is where relationships are stored. +type leadR struct { + ComplianceReportRequests ComplianceReportRequestSlice // compliance_report_request.compliance_report_request_lead_id_fkey + CreatorUser *User // lead.lead_creator_fkey + Organization *Organization // lead.lead_organization_id_fkey + Site *Site // lead.lead_site_id_site_version_fkey +} + +func buildLeadColumns(alias string) leadColumns { + return leadColumns{ + ColumnsExpr: expr.NewColumnsExpr( + "created", "creator", "id", "organization_id", "site_id", "site_version", "type_", + ).WithParent("lead"), + tableAlias: alias, + Created: psql.Quote(alias, "created"), + Creator: psql.Quote(alias, "creator"), + ID: psql.Quote(alias, "id"), + OrganizationID: psql.Quote(alias, "organization_id"), + SiteID: psql.Quote(alias, "site_id"), + SiteVersion: psql.Quote(alias, "site_version"), + Type: psql.Quote(alias, "type_"), + } +} + +type leadColumns struct { + expr.ColumnsExpr + tableAlias string + Created psql.Expression + Creator psql.Expression + ID psql.Expression + OrganizationID psql.Expression + SiteID psql.Expression + SiteVersion psql.Expression + Type psql.Expression +} + +func (c leadColumns) Alias() string { + return c.tableAlias +} + +func (leadColumns) AliasedAs(alias string) leadColumns { + return buildLeadColumns(alias) +} + +// LeadSetter is used for insert/upsert/update operations +// All values are optional, and do not have to be set +// Generated columns are not included +type LeadSetter struct { + Created omit.Val[time.Time] `db:"created" ` + Creator omit.Val[int32] `db:"creator" ` + ID omit.Val[int32] `db:"id,pk" ` + OrganizationID omit.Val[int32] `db:"organization_id" ` + SiteID omitnull.Val[int32] `db:"site_id" ` + SiteVersion omitnull.Val[int32] `db:"site_version" ` + Type omit.Val[enums.Leadtype] `db:"type_" ` +} + +func (s LeadSetter) SetColumns() []string { + vals := make([]string, 0, 7) + if s.Created.IsValue() { + vals = append(vals, "created") + } + if s.Creator.IsValue() { + vals = append(vals, "creator") + } + if s.ID.IsValue() { + vals = append(vals, "id") + } + if s.OrganizationID.IsValue() { + vals = append(vals, "organization_id") + } + if !s.SiteID.IsUnset() { + vals = append(vals, "site_id") + } + if !s.SiteVersion.IsUnset() { + vals = append(vals, "site_version") + } + if s.Type.IsValue() { + vals = append(vals, "type_") + } + return vals +} + +func (s LeadSetter) Overwrite(t *Lead) { + if s.Created.IsValue() { + t.Created = s.Created.MustGet() + } + if s.Creator.IsValue() { + t.Creator = s.Creator.MustGet() + } + if s.ID.IsValue() { + t.ID = s.ID.MustGet() + } + if s.OrganizationID.IsValue() { + t.OrganizationID = s.OrganizationID.MustGet() + } + if !s.SiteID.IsUnset() { + t.SiteID = s.SiteID.MustGetNull() + } + if !s.SiteVersion.IsUnset() { + t.SiteVersion = s.SiteVersion.MustGetNull() + } + if s.Type.IsValue() { + t.Type = s.Type.MustGet() + } +} + +func (s *LeadSetter) Apply(q *dialect.InsertQuery) { + q.AppendHooks(func(ctx context.Context, exec bob.Executor) (context.Context, error) { + return Leads.BeforeInsertHooks.RunHooks(ctx, exec, s) + }) + + q.AppendValues(bob.ExpressionFunc(func(ctx context.Context, w io.StringWriter, d bob.Dialect, start int) ([]any, error) { + vals := make([]bob.Expression, 7) + if s.Created.IsValue() { + vals[0] = psql.Arg(s.Created.MustGet()) + } else { + vals[0] = psql.Raw("DEFAULT") + } + + if s.Creator.IsValue() { + vals[1] = psql.Arg(s.Creator.MustGet()) + } else { + vals[1] = psql.Raw("DEFAULT") + } + + if s.ID.IsValue() { + vals[2] = psql.Arg(s.ID.MustGet()) + } else { + vals[2] = psql.Raw("DEFAULT") + } + + if s.OrganizationID.IsValue() { + vals[3] = psql.Arg(s.OrganizationID.MustGet()) + } else { + vals[3] = psql.Raw("DEFAULT") + } + + if !s.SiteID.IsUnset() { + vals[4] = psql.Arg(s.SiteID.MustGetNull()) + } else { + vals[4] = psql.Raw("DEFAULT") + } + + if !s.SiteVersion.IsUnset() { + vals[5] = psql.Arg(s.SiteVersion.MustGetNull()) + } else { + vals[5] = psql.Raw("DEFAULT") + } + + if s.Type.IsValue() { + vals[6] = psql.Arg(s.Type.MustGet()) + } else { + vals[6] = psql.Raw("DEFAULT") + } + + return bob.ExpressSlice(ctx, w, d, start, vals, "", ", ", "") + })) +} + +func (s LeadSetter) UpdateMod() bob.Mod[*dialect.UpdateQuery] { + return um.Set(s.Expressions()...) +} + +func (s LeadSetter) Expressions(prefix ...string) []bob.Expression { + exprs := make([]bob.Expression, 0, 7) + + if s.Created.IsValue() { + exprs = append(exprs, expr.Join{Sep: " = ", Exprs: []bob.Expression{ + psql.Quote(append(prefix, "created")...), + psql.Arg(s.Created), + }}) + } + + if s.Creator.IsValue() { + exprs = append(exprs, expr.Join{Sep: " = ", Exprs: []bob.Expression{ + psql.Quote(append(prefix, "creator")...), + psql.Arg(s.Creator), + }}) + } + + if s.ID.IsValue() { + exprs = append(exprs, expr.Join{Sep: " = ", Exprs: []bob.Expression{ + psql.Quote(append(prefix, "id")...), + psql.Arg(s.ID), + }}) + } + + if s.OrganizationID.IsValue() { + exprs = append(exprs, expr.Join{Sep: " = ", Exprs: []bob.Expression{ + psql.Quote(append(prefix, "organization_id")...), + psql.Arg(s.OrganizationID), + }}) + } + + if !s.SiteID.IsUnset() { + exprs = append(exprs, expr.Join{Sep: " = ", Exprs: []bob.Expression{ + psql.Quote(append(prefix, "site_id")...), + psql.Arg(s.SiteID), + }}) + } + + if !s.SiteVersion.IsUnset() { + exprs = append(exprs, expr.Join{Sep: " = ", Exprs: []bob.Expression{ + psql.Quote(append(prefix, "site_version")...), + psql.Arg(s.SiteVersion), + }}) + } + + if s.Type.IsValue() { + exprs = append(exprs, expr.Join{Sep: " = ", Exprs: []bob.Expression{ + psql.Quote(append(prefix, "type_")...), + psql.Arg(s.Type), + }}) + } + + return exprs +} + +// FindLead retrieves a single record by primary key +// If cols is empty Find will return all columns. +func FindLead(ctx context.Context, exec bob.Executor, IDPK int32, cols ...string) (*Lead, error) { + if len(cols) == 0 { + return Leads.Query( + sm.Where(Leads.Columns.ID.EQ(psql.Arg(IDPK))), + ).One(ctx, exec) + } + + return Leads.Query( + sm.Where(Leads.Columns.ID.EQ(psql.Arg(IDPK))), + sm.Columns(Leads.Columns.Only(cols...)), + ).One(ctx, exec) +} + +// LeadExists checks the presence of a single record by primary key +func LeadExists(ctx context.Context, exec bob.Executor, IDPK int32) (bool, error) { + return Leads.Query( + sm.Where(Leads.Columns.ID.EQ(psql.Arg(IDPK))), + ).Exists(ctx, exec) +} + +// AfterQueryHook is called after Lead is retrieved from the database +func (o *Lead) AfterQueryHook(ctx context.Context, exec bob.Executor, queryType bob.QueryType) error { + var err error + + switch queryType { + case bob.QueryTypeSelect: + ctx, err = Leads.AfterSelectHooks.RunHooks(ctx, exec, LeadSlice{o}) + case bob.QueryTypeInsert: + ctx, err = Leads.AfterInsertHooks.RunHooks(ctx, exec, LeadSlice{o}) + case bob.QueryTypeUpdate: + ctx, err = Leads.AfterUpdateHooks.RunHooks(ctx, exec, LeadSlice{o}) + case bob.QueryTypeDelete: + ctx, err = Leads.AfterDeleteHooks.RunHooks(ctx, exec, LeadSlice{o}) + } + + return err +} + +// primaryKeyVals returns the primary key values of the Lead +func (o *Lead) primaryKeyVals() bob.Expression { + return psql.Arg(o.ID) +} + +func (o *Lead) pkEQ() dialect.Expression { + return psql.Quote("lead", "id").EQ(bob.ExpressionFunc(func(ctx context.Context, w io.StringWriter, d bob.Dialect, start int) ([]any, error) { + return o.primaryKeyVals().WriteSQL(ctx, w, d, start) + })) +} + +// Update uses an executor to update the Lead +func (o *Lead) Update(ctx context.Context, exec bob.Executor, s *LeadSetter) error { + v, err := Leads.Update(s.UpdateMod(), um.Where(o.pkEQ())).One(ctx, exec) + if err != nil { + return err + } + + o.R = v.R + *o = *v + + return nil +} + +// Delete deletes a single Lead record with an executor +func (o *Lead) Delete(ctx context.Context, exec bob.Executor) error { + _, err := Leads.Delete(dm.Where(o.pkEQ())).Exec(ctx, exec) + return err +} + +// Reload refreshes the Lead using the executor +func (o *Lead) Reload(ctx context.Context, exec bob.Executor) error { + o2, err := Leads.Query( + sm.Where(Leads.Columns.ID.EQ(psql.Arg(o.ID))), + ).One(ctx, exec) + if err != nil { + return err + } + o2.R = o.R + *o = *o2 + + return nil +} + +// AfterQueryHook is called after LeadSlice is retrieved from the database +func (o LeadSlice) AfterQueryHook(ctx context.Context, exec bob.Executor, queryType bob.QueryType) error { + var err error + + switch queryType { + case bob.QueryTypeSelect: + ctx, err = Leads.AfterSelectHooks.RunHooks(ctx, exec, o) + case bob.QueryTypeInsert: + ctx, err = Leads.AfterInsertHooks.RunHooks(ctx, exec, o) + case bob.QueryTypeUpdate: + ctx, err = Leads.AfterUpdateHooks.RunHooks(ctx, exec, o) + case bob.QueryTypeDelete: + ctx, err = Leads.AfterDeleteHooks.RunHooks(ctx, exec, o) + } + + return err +} + +func (o LeadSlice) pkIN() dialect.Expression { + if len(o) == 0 { + return psql.Raw("NULL") + } + + return psql.Quote("lead", "id").In(bob.ExpressionFunc(func(ctx context.Context, w io.StringWriter, d bob.Dialect, start int) ([]any, error) { + pkPairs := make([]bob.Expression, len(o)) + for i, row := range o { + pkPairs[i] = row.primaryKeyVals() + } + return bob.ExpressSlice(ctx, w, d, start, pkPairs, "", ", ", "") + })) +} + +// copyMatchingRows finds models in the given slice that have the same primary key +// then it first copies the existing relationships from the old model to the new model +// and then replaces the old model in the slice with the new model +func (o LeadSlice) copyMatchingRows(from ...*Lead) { + for i, old := range o { + for _, new := range from { + if new.ID != old.ID { + continue + } + new.R = old.R + o[i] = new + break + } + } +} + +// UpdateMod modifies an update query with "WHERE primary_key IN (o...)" +func (o LeadSlice) UpdateMod() bob.Mod[*dialect.UpdateQuery] { + return bob.ModFunc[*dialect.UpdateQuery](func(q *dialect.UpdateQuery) { + q.AppendHooks(func(ctx context.Context, exec bob.Executor) (context.Context, error) { + return Leads.BeforeUpdateHooks.RunHooks(ctx, exec, o) + }) + + q.AppendLoader(bob.LoaderFunc(func(ctx context.Context, exec bob.Executor, retrieved any) error { + var err error + switch retrieved := retrieved.(type) { + case *Lead: + o.copyMatchingRows(retrieved) + case []*Lead: + o.copyMatchingRows(retrieved...) + case LeadSlice: + o.copyMatchingRows(retrieved...) + default: + // If the retrieved value is not a Lead or a slice of Lead + // then run the AfterUpdateHooks on the slice + _, err = Leads.AfterUpdateHooks.RunHooks(ctx, exec, o) + } + + return err + })) + + q.AppendWhere(o.pkIN()) + }) +} + +// DeleteMod modifies an delete query with "WHERE primary_key IN (o...)" +func (o LeadSlice) DeleteMod() bob.Mod[*dialect.DeleteQuery] { + return bob.ModFunc[*dialect.DeleteQuery](func(q *dialect.DeleteQuery) { + q.AppendHooks(func(ctx context.Context, exec bob.Executor) (context.Context, error) { + return Leads.BeforeDeleteHooks.RunHooks(ctx, exec, o) + }) + + q.AppendLoader(bob.LoaderFunc(func(ctx context.Context, exec bob.Executor, retrieved any) error { + var err error + switch retrieved := retrieved.(type) { + case *Lead: + o.copyMatchingRows(retrieved) + case []*Lead: + o.copyMatchingRows(retrieved...) + case LeadSlice: + o.copyMatchingRows(retrieved...) + default: + // If the retrieved value is not a Lead or a slice of Lead + // then run the AfterDeleteHooks on the slice + _, err = Leads.AfterDeleteHooks.RunHooks(ctx, exec, o) + } + + return err + })) + + q.AppendWhere(o.pkIN()) + }) +} + +func (o LeadSlice) UpdateAll(ctx context.Context, exec bob.Executor, vals LeadSetter) error { + if len(o) == 0 { + return nil + } + + _, err := Leads.Update(vals.UpdateMod(), o.UpdateMod()).All(ctx, exec) + return err +} + +func (o LeadSlice) DeleteAll(ctx context.Context, exec bob.Executor) error { + if len(o) == 0 { + return nil + } + + _, err := Leads.Delete(o.DeleteMod()).Exec(ctx, exec) + return err +} + +func (o LeadSlice) ReloadAll(ctx context.Context, exec bob.Executor) error { + if len(o) == 0 { + return nil + } + + o2, err := Leads.Query(sm.Where(o.pkIN())).All(ctx, exec) + if err != nil { + return err + } + + o.copyMatchingRows(o2...) + + return nil +} + +// ComplianceReportRequests starts a query for related objects on compliance_report_request +func (o *Lead) ComplianceReportRequests(mods ...bob.Mod[*dialect.SelectQuery]) ComplianceReportRequestsQuery { + return ComplianceReportRequests.Query(append(mods, + sm.Where(ComplianceReportRequests.Columns.LeadID.EQ(psql.Arg(o.ID))), + )...) +} + +func (os LeadSlice) ComplianceReportRequests(mods ...bob.Mod[*dialect.SelectQuery]) ComplianceReportRequestsQuery { + pkID := make(pgtypes.Array[int32], 0, len(os)) + for _, o := range os { + if o == nil { + continue + } + pkID = append(pkID, o.ID) + } + PKArgExpr := psql.Select(sm.Columns( + psql.F("unnest", psql.Cast(psql.Arg(pkID), "integer[]")), + )) + + return ComplianceReportRequests.Query(append(mods, + sm.Where(psql.Group(ComplianceReportRequests.Columns.LeadID).OP("IN", PKArgExpr)), + )...) +} + +// CreatorUser starts a query for related objects on user_ +func (o *Lead) CreatorUser(mods ...bob.Mod[*dialect.SelectQuery]) UsersQuery { + return Users.Query(append(mods, + sm.Where(Users.Columns.ID.EQ(psql.Arg(o.Creator))), + )...) +} + +func (os LeadSlice) CreatorUser(mods ...bob.Mod[*dialect.SelectQuery]) UsersQuery { + pkCreator := make(pgtypes.Array[int32], 0, len(os)) + for _, o := range os { + if o == nil { + continue + } + pkCreator = append(pkCreator, o.Creator) + } + PKArgExpr := psql.Select(sm.Columns( + psql.F("unnest", psql.Cast(psql.Arg(pkCreator), "integer[]")), + )) + + return Users.Query(append(mods, + sm.Where(psql.Group(Users.Columns.ID).OP("IN", PKArgExpr)), + )...) +} + +// Organization starts a query for related objects on organization +func (o *Lead) Organization(mods ...bob.Mod[*dialect.SelectQuery]) OrganizationsQuery { + return Organizations.Query(append(mods, + sm.Where(Organizations.Columns.ID.EQ(psql.Arg(o.OrganizationID))), + )...) +} + +func (os LeadSlice) Organization(mods ...bob.Mod[*dialect.SelectQuery]) OrganizationsQuery { + pkOrganizationID := make(pgtypes.Array[int32], 0, len(os)) + for _, o := range os { + if o == nil { + continue + } + pkOrganizationID = append(pkOrganizationID, o.OrganizationID) + } + PKArgExpr := psql.Select(sm.Columns( + psql.F("unnest", psql.Cast(psql.Arg(pkOrganizationID), "integer[]")), + )) + + return Organizations.Query(append(mods, + sm.Where(psql.Group(Organizations.Columns.ID).OP("IN", PKArgExpr)), + )...) +} + +// Site starts a query for related objects on site +func (o *Lead) Site(mods ...bob.Mod[*dialect.SelectQuery]) SitesQuery { + return Sites.Query(append(mods, + sm.Where(Sites.Columns.ID.EQ(psql.Arg(o.SiteID))), sm.Where(Sites.Columns.Version.EQ(psql.Arg(o.SiteVersion))), + )...) +} + +func (os LeadSlice) Site(mods ...bob.Mod[*dialect.SelectQuery]) SitesQuery { + pkSiteID := make(pgtypes.Array[null.Val[int32]], 0, len(os)) + + pkSiteVersion := make(pgtypes.Array[null.Val[int32]], 0, len(os)) + for _, o := range os { + if o == nil { + continue + } + pkSiteID = append(pkSiteID, o.SiteID) + pkSiteVersion = append(pkSiteVersion, o.SiteVersion) + } + PKArgExpr := psql.Select(sm.Columns( + psql.F("unnest", psql.Cast(psql.Arg(pkSiteID), "integer[]")), + psql.F("unnest", psql.Cast(psql.Arg(pkSiteVersion), "integer[]")), + )) + + return Sites.Query(append(mods, + sm.Where(psql.Group(Sites.Columns.ID, Sites.Columns.Version).OP("IN", PKArgExpr)), + )...) +} + +func insertLeadComplianceReportRequests0(ctx context.Context, exec bob.Executor, complianceReportRequests1 []*ComplianceReportRequestSetter, lead0 *Lead) (ComplianceReportRequestSlice, error) { + for i := range complianceReportRequests1 { + complianceReportRequests1[i].LeadID = omitnull.From(lead0.ID) + } + + ret, err := ComplianceReportRequests.Insert(bob.ToMods(complianceReportRequests1...)).All(ctx, exec) + if err != nil { + return ret, fmt.Errorf("insertLeadComplianceReportRequests0: %w", err) + } + + return ret, nil +} + +func attachLeadComplianceReportRequests0(ctx context.Context, exec bob.Executor, count int, complianceReportRequests1 ComplianceReportRequestSlice, lead0 *Lead) (ComplianceReportRequestSlice, error) { + setter := &ComplianceReportRequestSetter{ + LeadID: omitnull.From(lead0.ID), + } + + err := complianceReportRequests1.UpdateAll(ctx, exec, *setter) + if err != nil { + return nil, fmt.Errorf("attachLeadComplianceReportRequests0: %w", err) + } + + return complianceReportRequests1, nil +} + +func (lead0 *Lead) InsertComplianceReportRequests(ctx context.Context, exec bob.Executor, related ...*ComplianceReportRequestSetter) error { + if len(related) == 0 { + return nil + } + + var err error + + complianceReportRequests1, err := insertLeadComplianceReportRequests0(ctx, exec, related, lead0) + if err != nil { + return err + } + + lead0.R.ComplianceReportRequests = append(lead0.R.ComplianceReportRequests, complianceReportRequests1...) + + for _, rel := range complianceReportRequests1 { + rel.R.Lead = lead0 + } + return nil +} + +func (lead0 *Lead) AttachComplianceReportRequests(ctx context.Context, exec bob.Executor, related ...*ComplianceReportRequest) error { + if len(related) == 0 { + return nil + } + + var err error + complianceReportRequests1 := ComplianceReportRequestSlice(related) + + _, err = attachLeadComplianceReportRequests0(ctx, exec, len(related), complianceReportRequests1, lead0) + if err != nil { + return err + } + + lead0.R.ComplianceReportRequests = append(lead0.R.ComplianceReportRequests, complianceReportRequests1...) + + for _, rel := range related { + rel.R.Lead = lead0 + } + + return nil +} + +func attachLeadCreatorUser0(ctx context.Context, exec bob.Executor, count int, lead0 *Lead, user1 *User) (*Lead, error) { + setter := &LeadSetter{ + Creator: omit.From(user1.ID), + } + + err := lead0.Update(ctx, exec, setter) + if err != nil { + return nil, fmt.Errorf("attachLeadCreatorUser0: %w", err) + } + + return lead0, nil +} + +func (lead0 *Lead) InsertCreatorUser(ctx context.Context, exec bob.Executor, related *UserSetter) error { + var err error + + user1, err := Users.Insert(related).One(ctx, exec) + if err != nil { + return fmt.Errorf("inserting related objects: %w", err) + } + + _, err = attachLeadCreatorUser0(ctx, exec, 1, lead0, user1) + if err != nil { + return err + } + + lead0.R.CreatorUser = user1 + + user1.R.CreatorLeads = append(user1.R.CreatorLeads, lead0) + + return nil +} + +func (lead0 *Lead) AttachCreatorUser(ctx context.Context, exec bob.Executor, user1 *User) error { + var err error + + _, err = attachLeadCreatorUser0(ctx, exec, 1, lead0, user1) + if err != nil { + return err + } + + lead0.R.CreatorUser = user1 + + user1.R.CreatorLeads = append(user1.R.CreatorLeads, lead0) + + return nil +} + +func attachLeadOrganization0(ctx context.Context, exec bob.Executor, count int, lead0 *Lead, organization1 *Organization) (*Lead, error) { + setter := &LeadSetter{ + OrganizationID: omit.From(organization1.ID), + } + + err := lead0.Update(ctx, exec, setter) + if err != nil { + return nil, fmt.Errorf("attachLeadOrganization0: %w", err) + } + + return lead0, nil +} + +func (lead0 *Lead) InsertOrganization(ctx context.Context, exec bob.Executor, related *OrganizationSetter) error { + var err error + + organization1, err := Organizations.Insert(related).One(ctx, exec) + if err != nil { + return fmt.Errorf("inserting related objects: %w", err) + } + + _, err = attachLeadOrganization0(ctx, exec, 1, lead0, organization1) + if err != nil { + return err + } + + lead0.R.Organization = organization1 + + organization1.R.Leads = append(organization1.R.Leads, lead0) + + return nil +} + +func (lead0 *Lead) AttachOrganization(ctx context.Context, exec bob.Executor, organization1 *Organization) error { + var err error + + _, err = attachLeadOrganization0(ctx, exec, 1, lead0, organization1) + if err != nil { + return err + } + + lead0.R.Organization = organization1 + + organization1.R.Leads = append(organization1.R.Leads, lead0) + + return nil +} + +func attachLeadSite0(ctx context.Context, exec bob.Executor, count int, lead0 *Lead, site1 *Site) (*Lead, error) { + setter := &LeadSetter{ + SiteID: omitnull.From(site1.ID), + SiteVersion: omitnull.From(site1.Version), + } + + err := lead0.Update(ctx, exec, setter) + if err != nil { + return nil, fmt.Errorf("attachLeadSite0: %w", err) + } + + return lead0, nil +} + +func (lead0 *Lead) InsertSite(ctx context.Context, exec bob.Executor, related *SiteSetter) error { + var err error + + site1, err := Sites.Insert(related).One(ctx, exec) + if err != nil { + return fmt.Errorf("inserting related objects: %w", err) + } + + _, err = attachLeadSite0(ctx, exec, 1, lead0, site1) + if err != nil { + return err + } + + lead0.R.Site = site1 + + site1.R.Leads = append(site1.R.Leads, lead0) + + return nil +} + +func (lead0 *Lead) AttachSite(ctx context.Context, exec bob.Executor, site1 *Site) error { + var err error + + _, err = attachLeadSite0(ctx, exec, 1, lead0, site1) + if err != nil { + return err + } + + lead0.R.Site = site1 + + site1.R.Leads = append(site1.R.Leads, lead0) + + return nil +} + +type leadWhere[Q psql.Filterable] struct { + Created psql.WhereMod[Q, time.Time] + Creator psql.WhereMod[Q, int32] + ID psql.WhereMod[Q, int32] + OrganizationID psql.WhereMod[Q, int32] + SiteID psql.WhereNullMod[Q, int32] + SiteVersion psql.WhereNullMod[Q, int32] + Type psql.WhereMod[Q, enums.Leadtype] +} + +func (leadWhere[Q]) AliasedAs(alias string) leadWhere[Q] { + return buildLeadWhere[Q](buildLeadColumns(alias)) +} + +func buildLeadWhere[Q psql.Filterable](cols leadColumns) leadWhere[Q] { + return leadWhere[Q]{ + Created: psql.Where[Q, time.Time](cols.Created), + Creator: psql.Where[Q, int32](cols.Creator), + ID: psql.Where[Q, int32](cols.ID), + OrganizationID: psql.Where[Q, int32](cols.OrganizationID), + SiteID: psql.WhereNull[Q, int32](cols.SiteID), + SiteVersion: psql.WhereNull[Q, int32](cols.SiteVersion), + Type: psql.Where[Q, enums.Leadtype](cols.Type), + } +} + +func (o *Lead) Preload(name string, retrieved any) error { + if o == nil { + return nil + } + + switch name { + case "ComplianceReportRequests": + rels, ok := retrieved.(ComplianceReportRequestSlice) + if !ok { + return fmt.Errorf("lead cannot load %T as %q", retrieved, name) + } + + o.R.ComplianceReportRequests = rels + + for _, rel := range rels { + if rel != nil { + rel.R.Lead = o + } + } + return nil + case "CreatorUser": + rel, ok := retrieved.(*User) + if !ok { + return fmt.Errorf("lead cannot load %T as %q", retrieved, name) + } + + o.R.CreatorUser = rel + + if rel != nil { + rel.R.CreatorLeads = LeadSlice{o} + } + return nil + case "Organization": + rel, ok := retrieved.(*Organization) + if !ok { + return fmt.Errorf("lead cannot load %T as %q", retrieved, name) + } + + o.R.Organization = rel + + if rel != nil { + rel.R.Leads = LeadSlice{o} + } + return nil + case "Site": + rel, ok := retrieved.(*Site) + if !ok { + return fmt.Errorf("lead cannot load %T as %q", retrieved, name) + } + + o.R.Site = rel + + if rel != nil { + rel.R.Leads = LeadSlice{o} + } + return nil + default: + return fmt.Errorf("lead has no relationship %q", name) + } +} + +type leadPreloader struct { + CreatorUser func(...psql.PreloadOption) psql.Preloader + Organization func(...psql.PreloadOption) psql.Preloader + Site func(...psql.PreloadOption) psql.Preloader +} + +func buildLeadPreloader() leadPreloader { + return leadPreloader{ + CreatorUser: func(opts ...psql.PreloadOption) psql.Preloader { + return psql.Preload[*User, UserSlice](psql.PreloadRel{ + Name: "CreatorUser", + Sides: []psql.PreloadSide{ + { + From: Leads, + To: Users, + FromColumns: []string{"creator"}, + ToColumns: []string{"id"}, + }, + }, + }, Users.Columns.Names(), opts...) + }, + Organization: func(opts ...psql.PreloadOption) psql.Preloader { + return psql.Preload[*Organization, OrganizationSlice](psql.PreloadRel{ + Name: "Organization", + Sides: []psql.PreloadSide{ + { + From: Leads, + To: Organizations, + FromColumns: []string{"organization_id"}, + ToColumns: []string{"id"}, + }, + }, + }, Organizations.Columns.Names(), opts...) + }, + Site: func(opts ...psql.PreloadOption) psql.Preloader { + return psql.Preload[*Site, SiteSlice](psql.PreloadRel{ + Name: "Site", + Sides: []psql.PreloadSide{ + { + From: Leads, + To: Sites, + FromColumns: []string{"site_id", "site_version"}, + ToColumns: []string{"id", "version"}, + }, + }, + }, Sites.Columns.Names(), opts...) + }, + } +} + +type leadThenLoader[Q orm.Loadable] struct { + ComplianceReportRequests func(...bob.Mod[*dialect.SelectQuery]) orm.Loader[Q] + CreatorUser func(...bob.Mod[*dialect.SelectQuery]) orm.Loader[Q] + Organization func(...bob.Mod[*dialect.SelectQuery]) orm.Loader[Q] + Site func(...bob.Mod[*dialect.SelectQuery]) orm.Loader[Q] +} + +func buildLeadThenLoader[Q orm.Loadable]() leadThenLoader[Q] { + type ComplianceReportRequestsLoadInterface interface { + LoadComplianceReportRequests(context.Context, bob.Executor, ...bob.Mod[*dialect.SelectQuery]) error + } + type CreatorUserLoadInterface interface { + LoadCreatorUser(context.Context, bob.Executor, ...bob.Mod[*dialect.SelectQuery]) error + } + type OrganizationLoadInterface interface { + LoadOrganization(context.Context, bob.Executor, ...bob.Mod[*dialect.SelectQuery]) error + } + type SiteLoadInterface interface { + LoadSite(context.Context, bob.Executor, ...bob.Mod[*dialect.SelectQuery]) error + } + + return leadThenLoader[Q]{ + ComplianceReportRequests: thenLoadBuilder[Q]( + "ComplianceReportRequests", + func(ctx context.Context, exec bob.Executor, retrieved ComplianceReportRequestsLoadInterface, mods ...bob.Mod[*dialect.SelectQuery]) error { + return retrieved.LoadComplianceReportRequests(ctx, exec, mods...) + }, + ), + CreatorUser: thenLoadBuilder[Q]( + "CreatorUser", + func(ctx context.Context, exec bob.Executor, retrieved CreatorUserLoadInterface, mods ...bob.Mod[*dialect.SelectQuery]) error { + return retrieved.LoadCreatorUser(ctx, exec, mods...) + }, + ), + Organization: thenLoadBuilder[Q]( + "Organization", + func(ctx context.Context, exec bob.Executor, retrieved OrganizationLoadInterface, mods ...bob.Mod[*dialect.SelectQuery]) error { + return retrieved.LoadOrganization(ctx, exec, mods...) + }, + ), + Site: thenLoadBuilder[Q]( + "Site", + func(ctx context.Context, exec bob.Executor, retrieved SiteLoadInterface, mods ...bob.Mod[*dialect.SelectQuery]) error { + return retrieved.LoadSite(ctx, exec, mods...) + }, + ), + } +} + +// LoadComplianceReportRequests loads the lead's ComplianceReportRequests into the .R struct +func (o *Lead) LoadComplianceReportRequests(ctx context.Context, exec bob.Executor, mods ...bob.Mod[*dialect.SelectQuery]) error { + if o == nil { + return nil + } + + // Reset the relationship + o.R.ComplianceReportRequests = nil + + related, err := o.ComplianceReportRequests(mods...).All(ctx, exec) + if err != nil { + return err + } + + for _, rel := range related { + rel.R.Lead = o + } + + o.R.ComplianceReportRequests = related + return nil +} + +// LoadComplianceReportRequests loads the lead's ComplianceReportRequests into the .R struct +func (os LeadSlice) LoadComplianceReportRequests(ctx context.Context, exec bob.Executor, mods ...bob.Mod[*dialect.SelectQuery]) error { + if len(os) == 0 { + return nil + } + + complianceReportRequests, err := os.ComplianceReportRequests(mods...).All(ctx, exec) + if err != nil { + return err + } + + for _, o := range os { + if o == nil { + continue + } + + o.R.ComplianceReportRequests = nil + } + + for _, o := range os { + if o == nil { + continue + } + + for _, rel := range complianceReportRequests { + + if !rel.LeadID.IsValue() { + continue + } + if !(rel.LeadID.IsValue() && o.ID == rel.LeadID.MustGet()) { + continue + } + + rel.R.Lead = o + + o.R.ComplianceReportRequests = append(o.R.ComplianceReportRequests, rel) + } + } + + return nil +} + +// LoadCreatorUser loads the lead's CreatorUser into the .R struct +func (o *Lead) LoadCreatorUser(ctx context.Context, exec bob.Executor, mods ...bob.Mod[*dialect.SelectQuery]) error { + if o == nil { + return nil + } + + // Reset the relationship + o.R.CreatorUser = nil + + related, err := o.CreatorUser(mods...).One(ctx, exec) + if err != nil { + return err + } + + related.R.CreatorLeads = LeadSlice{o} + + o.R.CreatorUser = related + return nil +} + +// LoadCreatorUser loads the lead's CreatorUser into the .R struct +func (os LeadSlice) LoadCreatorUser(ctx context.Context, exec bob.Executor, mods ...bob.Mod[*dialect.SelectQuery]) error { + if len(os) == 0 { + return nil + } + + users, err := os.CreatorUser(mods...).All(ctx, exec) + if err != nil { + return err + } + + for _, o := range os { + if o == nil { + continue + } + + for _, rel := range users { + + if !(o.Creator == rel.ID) { + continue + } + + rel.R.CreatorLeads = append(rel.R.CreatorLeads, o) + + o.R.CreatorUser = rel + break + } + } + + return nil +} + +// LoadOrganization loads the lead's Organization into the .R struct +func (o *Lead) LoadOrganization(ctx context.Context, exec bob.Executor, mods ...bob.Mod[*dialect.SelectQuery]) error { + if o == nil { + return nil + } + + // Reset the relationship + o.R.Organization = nil + + related, err := o.Organization(mods...).One(ctx, exec) + if err != nil { + return err + } + + related.R.Leads = LeadSlice{o} + + o.R.Organization = related + return nil +} + +// LoadOrganization loads the lead's Organization into the .R struct +func (os LeadSlice) LoadOrganization(ctx context.Context, exec bob.Executor, mods ...bob.Mod[*dialect.SelectQuery]) error { + if len(os) == 0 { + return nil + } + + organizations, err := os.Organization(mods...).All(ctx, exec) + if err != nil { + return err + } + + for _, o := range os { + if o == nil { + continue + } + + for _, rel := range organizations { + + if !(o.OrganizationID == rel.ID) { + continue + } + + rel.R.Leads = append(rel.R.Leads, o) + + o.R.Organization = rel + break + } + } + + return nil +} + +// LoadSite loads the lead's Site into the .R struct +func (o *Lead) LoadSite(ctx context.Context, exec bob.Executor, mods ...bob.Mod[*dialect.SelectQuery]) error { + if o == nil { + return nil + } + + // Reset the relationship + o.R.Site = nil + + related, err := o.Site(mods...).One(ctx, exec) + if err != nil { + return err + } + + related.R.Leads = LeadSlice{o} + + o.R.Site = related + return nil +} + +// LoadSite loads the lead's Site into the .R struct +func (os LeadSlice) LoadSite(ctx context.Context, exec bob.Executor, mods ...bob.Mod[*dialect.SelectQuery]) error { + if len(os) == 0 { + return nil + } + + sites, err := os.Site(mods...).All(ctx, exec) + if err != nil { + return err + } + + for _, o := range os { + if o == nil { + continue + } + + for _, rel := range sites { + if !o.SiteID.IsValue() { + continue + } + + if !(o.SiteID.IsValue() && o.SiteID.MustGet() == rel.ID) { + continue + } + if !o.SiteVersion.IsValue() { + continue + } + + if !(o.SiteVersion.IsValue() && o.SiteVersion.MustGet() == rel.Version) { + continue + } + + rel.R.Leads = append(rel.R.Leads, o) + + o.R.Site = rel + break + } + } + + return nil +} + +// leadC is where relationship counts are stored. +type leadC struct { + ComplianceReportRequests *int64 +} + +// PreloadCount sets a count in the C struct by name +func (o *Lead) PreloadCount(name string, count int64) error { + if o == nil { + return nil + } + + switch name { + case "ComplianceReportRequests": + o.C.ComplianceReportRequests = &count + } + return nil +} + +type leadCountPreloader struct { + ComplianceReportRequests func(...bob.Mod[*dialect.SelectQuery]) psql.Preloader +} + +func buildLeadCountPreloader() leadCountPreloader { + return leadCountPreloader{ + ComplianceReportRequests: func(mods ...bob.Mod[*dialect.SelectQuery]) psql.Preloader { + return countPreloader[*Lead]("ComplianceReportRequests", func(parent string) bob.Expression { + // Build a correlated subquery: (SELECT COUNT(*) FROM related WHERE fk = parent.pk) + if parent == "" { + parent = Leads.Alias() + } + + subqueryMods := []bob.Mod[*dialect.SelectQuery]{ + sm.Columns(psql.Raw("count(*)")), + + sm.From(ComplianceReportRequests.Name()), + sm.Where(psql.Quote(ComplianceReportRequests.Alias(), "lead_id").EQ(psql.Quote(parent, "id"))), + } + subqueryMods = append(subqueryMods, mods...) + return psql.Group(psql.Select(subqueryMods...).Expression) + }) + }, + } +} + +type leadCountThenLoader[Q orm.Loadable] struct { + ComplianceReportRequests func(...bob.Mod[*dialect.SelectQuery]) orm.Loader[Q] +} + +func buildLeadCountThenLoader[Q orm.Loadable]() leadCountThenLoader[Q] { + type ComplianceReportRequestsCountInterface interface { + LoadCountComplianceReportRequests(context.Context, bob.Executor, ...bob.Mod[*dialect.SelectQuery]) error + } + + return leadCountThenLoader[Q]{ + ComplianceReportRequests: countThenLoadBuilder[Q]( + "ComplianceReportRequests", + func(ctx context.Context, exec bob.Executor, retrieved ComplianceReportRequestsCountInterface, mods ...bob.Mod[*dialect.SelectQuery]) error { + return retrieved.LoadCountComplianceReportRequests(ctx, exec, mods...) + }, + ), + } +} + +// LoadCountComplianceReportRequests loads the count of ComplianceReportRequests into the C struct +func (o *Lead) LoadCountComplianceReportRequests(ctx context.Context, exec bob.Executor, mods ...bob.Mod[*dialect.SelectQuery]) error { + if o == nil { + return nil + } + + count, err := o.ComplianceReportRequests(mods...).Count(ctx, exec) + if err != nil { + return err + } + + o.C.ComplianceReportRequests = &count + return nil +} + +// LoadCountComplianceReportRequests loads the count of ComplianceReportRequests for a slice +func (os LeadSlice) LoadCountComplianceReportRequests(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.LoadCountComplianceReportRequests(ctx, exec, mods...); err != nil { + return err + } + } + + return nil +} + +type leadJoins[Q dialect.Joinable] struct { + typ string + ComplianceReportRequests modAs[Q, complianceReportRequestColumns] + CreatorUser modAs[Q, userColumns] + Organization modAs[Q, organizationColumns] + Site modAs[Q, siteColumns] +} + +func (j leadJoins[Q]) aliasedAs(alias string) leadJoins[Q] { + return buildLeadJoins[Q](buildLeadColumns(alias), j.typ) +} + +func buildLeadJoins[Q dialect.Joinable](cols leadColumns, typ string) leadJoins[Q] { + return leadJoins[Q]{ + typ: typ, + ComplianceReportRequests: modAs[Q, complianceReportRequestColumns]{ + c: ComplianceReportRequests.Columns, + f: func(to complianceReportRequestColumns) bob.Mod[Q] { + mods := make(mods.QueryMods[Q], 0, 1) + + { + mods = append(mods, dialect.Join[Q](typ, ComplianceReportRequests.Name().As(to.Alias())).On( + to.LeadID.EQ(cols.ID), + )) + } + + return mods + }, + }, + CreatorUser: modAs[Q, userColumns]{ + c: Users.Columns, + f: func(to userColumns) bob.Mod[Q] { + mods := make(mods.QueryMods[Q], 0, 1) + + { + mods = append(mods, dialect.Join[Q](typ, Users.Name().As(to.Alias())).On( + to.ID.EQ(cols.Creator), + )) + } + + return mods + }, + }, + Organization: modAs[Q, organizationColumns]{ + c: Organizations.Columns, + f: func(to organizationColumns) bob.Mod[Q] { + mods := make(mods.QueryMods[Q], 0, 1) + + { + mods = append(mods, dialect.Join[Q](typ, Organizations.Name().As(to.Alias())).On( + to.ID.EQ(cols.OrganizationID), + )) + } + + return mods + }, + }, + Site: modAs[Q, siteColumns]{ + c: Sites.Columns, + f: func(to siteColumns) bob.Mod[Q] { + mods := make(mods.QueryMods[Q], 0, 1) + + { + mods = append(mods, dialect.Join[Q](typ, Sites.Name().As(to.Alias())).On( + to.ID.EQ(cols.SiteID), to.Version.EQ(cols.SiteVersion), + )) + } + + return mods + }, + }, + } +} diff --git a/db/models/organization.bob.go b/db/models/organization.bob.go index d3fc4d16..74b5cdae 100644 --- a/db/models/organization.bob.go +++ b/db/models/organization.bob.go @@ -114,6 +114,7 @@ type organizationR struct { FieldseekerSyncs FieldseekerSyncSlice // fieldseeker_sync.fieldseeker_sync_organization_id_fkey Files FileuploadFileSlice // fileupload.file.file_organization_id_fkey H3Aggregations H3AggregationSlice // h3_aggregation.h3_aggregation_organization_id_fkey + Leads LeadSlice // lead.lead_organization_id_fkey NoteAudios NoteAudioSlice // note_audio.note_audio_organization_id_fkey NoteImages NoteImageSlice // note_image.note_image_organization_id_fkey ArcgisAccountAccount *ArcgisAccount // organization.organization_arcgis_account_id_fkey @@ -1759,6 +1760,30 @@ func (os OrganizationSlice) H3Aggregations(mods ...bob.Mod[*dialect.SelectQuery] )...) } +// Leads starts a query for related objects on lead +func (o *Organization) Leads(mods ...bob.Mod[*dialect.SelectQuery]) LeadsQuery { + return Leads.Query(append(mods, + sm.Where(Leads.Columns.OrganizationID.EQ(psql.Arg(o.ID))), + )...) +} + +func (os OrganizationSlice) Leads(mods ...bob.Mod[*dialect.SelectQuery]) LeadsQuery { + pkID := make(pgtypes.Array[int32], 0, len(os)) + for _, o := range os { + if o == nil { + continue + } + pkID = append(pkID, o.ID) + } + PKArgExpr := psql.Select(sm.Columns( + psql.F("unnest", psql.Cast(psql.Arg(pkID), "integer[]")), + )) + + return Leads.Query(append(mods, + sm.Where(psql.Group(Leads.Columns.OrganizationID).OP("IN", PKArgExpr)), + )...) +} + // NoteAudios starts a query for related objects on note_audio func (o *Organization) NoteAudios(mods ...bob.Mod[*dialect.SelectQuery]) NoteAudiosQuery { return NoteAudios.Query(append(mods, @@ -4349,6 +4374,74 @@ func (organization0 *Organization) AttachH3Aggregations(ctx context.Context, exe return nil } +func insertOrganizationLeads0(ctx context.Context, exec bob.Executor, leads1 []*LeadSetter, organization0 *Organization) (LeadSlice, error) { + for i := range leads1 { + leads1[i].OrganizationID = omit.From(organization0.ID) + } + + ret, err := Leads.Insert(bob.ToMods(leads1...)).All(ctx, exec) + if err != nil { + return ret, fmt.Errorf("insertOrganizationLeads0: %w", err) + } + + return ret, nil +} + +func attachOrganizationLeads0(ctx context.Context, exec bob.Executor, count int, leads1 LeadSlice, organization0 *Organization) (LeadSlice, error) { + setter := &LeadSetter{ + OrganizationID: omit.From(organization0.ID), + } + + err := leads1.UpdateAll(ctx, exec, *setter) + if err != nil { + return nil, fmt.Errorf("attachOrganizationLeads0: %w", err) + } + + return leads1, nil +} + +func (organization0 *Organization) InsertLeads(ctx context.Context, exec bob.Executor, related ...*LeadSetter) error { + if len(related) == 0 { + return nil + } + + var err error + + leads1, err := insertOrganizationLeads0(ctx, exec, related, organization0) + if err != nil { + return err + } + + organization0.R.Leads = append(organization0.R.Leads, leads1...) + + for _, rel := range leads1 { + rel.R.Organization = organization0 + } + return nil +} + +func (organization0 *Organization) AttachLeads(ctx context.Context, exec bob.Executor, related ...*Lead) error { + if len(related) == 0 { + return nil + } + + var err error + leads1 := LeadSlice(related) + + _, err = attachOrganizationLeads0(ctx, exec, len(related), leads1, organization0) + if err != nil { + return err + } + + organization0.R.Leads = append(organization0.R.Leads, leads1...) + + for _, rel := range related { + rel.R.Organization = organization0 + } + + return nil +} + func insertOrganizationNoteAudios0(ctx context.Context, exec bob.Executor, noteAudios1 []*NoteAudioSetter, organization0 *Organization) (NoteAudioSlice, error) { for i := range noteAudios1 { noteAudios1[i].OrganizationID = omit.From(organization0.ID) @@ -5487,6 +5580,20 @@ func (o *Organization) Preload(name string, retrieved any) error { o.R.H3Aggregations = rels + for _, rel := range rels { + if rel != nil { + rel.R.Organization = o + } + } + return nil + case "Leads": + rels, ok := retrieved.(LeadSlice) + if !ok { + return fmt.Errorf("organization cannot load %T as %q", retrieved, name) + } + + o.R.Leads = rels + for _, rel := range rels { if rel != nil { rel.R.Organization = o @@ -5692,6 +5799,7 @@ type organizationThenLoader[Q orm.Loadable] struct { FieldseekerSyncs func(...bob.Mod[*dialect.SelectQuery]) orm.Loader[Q] Files func(...bob.Mod[*dialect.SelectQuery]) orm.Loader[Q] H3Aggregations func(...bob.Mod[*dialect.SelectQuery]) orm.Loader[Q] + Leads func(...bob.Mod[*dialect.SelectQuery]) orm.Loader[Q] NoteAudios func(...bob.Mod[*dialect.SelectQuery]) orm.Loader[Q] NoteImages func(...bob.Mod[*dialect.SelectQuery]) orm.Loader[Q] ArcgisAccountAccount func(...bob.Mod[*dialect.SelectQuery]) orm.Loader[Q] @@ -5809,6 +5917,9 @@ func buildOrganizationThenLoader[Q orm.Loadable]() organizationThenLoader[Q] { type H3AggregationsLoadInterface interface { LoadH3Aggregations(context.Context, bob.Executor, ...bob.Mod[*dialect.SelectQuery]) error } + type LeadsLoadInterface interface { + LoadLeads(context.Context, bob.Executor, ...bob.Mod[*dialect.SelectQuery]) error + } type NoteAudiosLoadInterface interface { LoadNoteAudios(context.Context, bob.Executor, ...bob.Mod[*dialect.SelectQuery]) error } @@ -6048,6 +6159,12 @@ func buildOrganizationThenLoader[Q orm.Loadable]() organizationThenLoader[Q] { return retrieved.LoadH3Aggregations(ctx, exec, mods...) }, ), + Leads: thenLoadBuilder[Q]( + "Leads", + func(ctx context.Context, exec bob.Executor, retrieved LeadsLoadInterface, mods ...bob.Mod[*dialect.SelectQuery]) error { + return retrieved.LoadLeads(ctx, exec, mods...) + }, + ), NoteAudios: thenLoadBuilder[Q]( "NoteAudios", func(ctx context.Context, exec bob.Executor, retrieved NoteAudiosLoadInterface, mods ...bob.Mod[*dialect.SelectQuery]) error { @@ -8280,6 +8397,67 @@ func (os OrganizationSlice) LoadH3Aggregations(ctx context.Context, exec bob.Exe return nil } +// LoadLeads loads the organization's Leads into the .R struct +func (o *Organization) LoadLeads(ctx context.Context, exec bob.Executor, mods ...bob.Mod[*dialect.SelectQuery]) error { + if o == nil { + return nil + } + + // Reset the relationship + o.R.Leads = nil + + related, err := o.Leads(mods...).All(ctx, exec) + if err != nil { + return err + } + + for _, rel := range related { + rel.R.Organization = o + } + + o.R.Leads = related + return nil +} + +// LoadLeads loads the organization's Leads into the .R struct +func (os OrganizationSlice) LoadLeads(ctx context.Context, exec bob.Executor, mods ...bob.Mod[*dialect.SelectQuery]) error { + if len(os) == 0 { + return nil + } + + leads, err := os.Leads(mods...).All(ctx, exec) + if err != nil { + return err + } + + for _, o := range os { + if o == nil { + continue + } + + o.R.Leads = nil + } + + for _, o := range os { + if o == nil { + continue + } + + for _, rel := range leads { + + if !(o.ID == rel.OrganizationID) { + continue + } + + rel.R.Organization = o + + o.R.Leads = append(o.R.Leads, rel) + } + } + + return nil +} + // LoadNoteAudios loads the organization's NoteAudios into the .R struct func (o *Organization) LoadNoteAudios(ctx context.Context, exec bob.Executor, mods ...bob.Mod[*dialect.SelectQuery]) error { if o == nil { @@ -8863,6 +9041,7 @@ type organizationC struct { FieldseekerSyncs *int64 Files *int64 H3Aggregations *int64 + Leads *int64 NoteAudios *int64 NoteImages *int64 Nuisances *int64 @@ -8949,6 +9128,8 @@ func (o *Organization) PreloadCount(name string, count int64) error { o.C.Files = &count case "H3Aggregations": o.C.H3Aggregations = &count + case "Leads": + o.C.Leads = &count case "NoteAudios": o.C.NoteAudios = &count case "NoteImages": @@ -9003,6 +9184,7 @@ type organizationCountPreloader struct { FieldseekerSyncs func(...bob.Mod[*dialect.SelectQuery]) psql.Preloader Files func(...bob.Mod[*dialect.SelectQuery]) psql.Preloader H3Aggregations func(...bob.Mod[*dialect.SelectQuery]) psql.Preloader + Leads func(...bob.Mod[*dialect.SelectQuery]) psql.Preloader NoteAudios func(...bob.Mod[*dialect.SelectQuery]) psql.Preloader NoteImages func(...bob.Mod[*dialect.SelectQuery]) psql.Preloader Nuisances func(...bob.Mod[*dialect.SelectQuery]) psql.Preloader @@ -9615,6 +9797,23 @@ func buildOrganizationCountPreloader() organizationCountPreloader { return psql.Group(psql.Select(subqueryMods...).Expression) }) }, + Leads: func(mods ...bob.Mod[*dialect.SelectQuery]) psql.Preloader { + return countPreloader[*Organization]("Leads", func(parent string) bob.Expression { + // Build a correlated subquery: (SELECT COUNT(*) FROM related WHERE fk = parent.pk) + if parent == "" { + parent = Organizations.Alias() + } + + subqueryMods := []bob.Mod[*dialect.SelectQuery]{ + sm.Columns(psql.Raw("count(*)")), + + sm.From(Leads.Name()), + sm.Where(psql.Quote(Leads.Alias(), "organization_id").EQ(psql.Quote(parent, "id"))), + } + subqueryMods = append(subqueryMods, mods...) + return psql.Group(psql.Select(subqueryMods...).Expression) + }) + }, NoteAudios: func(mods ...bob.Mod[*dialect.SelectQuery]) psql.Preloader { return countPreloader[*Organization]("NoteAudios", func(parent string) bob.Expression { // Build a correlated subquery: (SELECT COUNT(*) FROM related WHERE fk = parent.pk) @@ -9773,6 +9972,7 @@ type organizationCountThenLoader[Q orm.Loadable] struct { FieldseekerSyncs func(...bob.Mod[*dialect.SelectQuery]) orm.Loader[Q] Files func(...bob.Mod[*dialect.SelectQuery]) orm.Loader[Q] H3Aggregations func(...bob.Mod[*dialect.SelectQuery]) orm.Loader[Q] + Leads func(...bob.Mod[*dialect.SelectQuery]) orm.Loader[Q] NoteAudios func(...bob.Mod[*dialect.SelectQuery]) orm.Loader[Q] NoteImages func(...bob.Mod[*dialect.SelectQuery]) orm.Loader[Q] Nuisances func(...bob.Mod[*dialect.SelectQuery]) orm.Loader[Q] @@ -9888,6 +10088,9 @@ func buildOrganizationCountThenLoader[Q orm.Loadable]() organizationCountThenLoa type H3AggregationsCountInterface interface { LoadCountH3Aggregations(context.Context, bob.Executor, ...bob.Mod[*dialect.SelectQuery]) error } + type LeadsCountInterface interface { + LoadCountLeads(context.Context, bob.Executor, ...bob.Mod[*dialect.SelectQuery]) error + } type NoteAudiosCountInterface interface { LoadCountNoteAudios(context.Context, bob.Executor, ...bob.Mod[*dialect.SelectQuery]) error } @@ -10121,6 +10324,12 @@ func buildOrganizationCountThenLoader[Q orm.Loadable]() organizationCountThenLoa return retrieved.LoadCountH3Aggregations(ctx, exec, mods...) }, ), + Leads: countThenLoadBuilder[Q]( + "Leads", + func(ctx context.Context, exec bob.Executor, retrieved LeadsCountInterface, mods ...bob.Mod[*dialect.SelectQuery]) error { + return retrieved.LoadCountLeads(ctx, exec, mods...) + }, + ), NoteAudios: countThenLoadBuilder[Q]( "NoteAudios", func(ctx context.Context, exec bob.Executor, retrieved NoteAudiosCountInterface, mods ...bob.Mod[*dialect.SelectQuery]) error { @@ -11216,6 +11425,36 @@ func (os OrganizationSlice) LoadCountH3Aggregations(ctx context.Context, exec bo return nil } +// LoadCountLeads loads the count of Leads into the C struct +func (o *Organization) LoadCountLeads(ctx context.Context, exec bob.Executor, mods ...bob.Mod[*dialect.SelectQuery]) error { + if o == nil { + return nil + } + + count, err := o.Leads(mods...).Count(ctx, exec) + if err != nil { + return err + } + + o.C.Leads = &count + return nil +} + +// LoadCountLeads loads the count of Leads for a slice +func (os OrganizationSlice) LoadCountLeads(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.LoadCountLeads(ctx, exec, mods...); err != nil { + return err + } + } + + return nil +} + // LoadCountNoteAudios loads the count of NoteAudios into the C struct func (o *Organization) LoadCountNoteAudios(ctx context.Context, exec bob.Executor, mods ...bob.Mod[*dialect.SelectQuery]) error { if o == nil { @@ -11463,6 +11702,7 @@ type organizationJoins[Q dialect.Joinable] struct { FieldseekerSyncs modAs[Q, fieldseekerSyncColumns] Files modAs[Q, fileuploadFileColumns] H3Aggregations modAs[Q, h3AggregationColumns] + Leads modAs[Q, leadColumns] NoteAudios modAs[Q, noteAudioColumns] NoteImages modAs[Q, noteImageColumns] ArcgisAccountAccount modAs[Q, arcgisAccountColumns] @@ -11987,6 +12227,20 @@ func buildOrganizationJoins[Q dialect.Joinable](cols organizationColumns, typ st return mods }, }, + Leads: modAs[Q, leadColumns]{ + c: Leads.Columns, + f: func(to leadColumns) bob.Mod[Q] { + mods := make(mods.QueryMods[Q], 0, 1) + + { + mods = append(mods, dialect.Join[Q](typ, Leads.Name().As(to.Alias())).On( + to.OrganizationID.EQ(cols.ID), + )) + } + + return mods + }, + }, NoteAudios: modAs[Q, noteAudioColumns]{ c: NoteAudios.Columns, f: func(to noteAudioColumns) bob.Mod[Q] { diff --git a/db/models/site.bob.go b/db/models/site.bob.go index fe08a033..8d2b5ce7 100644 --- a/db/models/site.bob.go +++ b/db/models/site.bob.go @@ -57,13 +57,13 @@ type SitesQuery = *psql.ViewQuery[*Site, SiteSlice] // siteR is where relationships are stored. type siteR struct { - ComplianceReportRequests ComplianceReportRequestSlice // compliance_report_request.compliance_report_request_site_id_site_version_fkey - Pools PoolSlice // pool.pool_site_id_site_version_fkey - Residents ResidentSlice // resident.resident_site_id_site_version_fkey - Address *Address // site.site_address_id_fkey - CreatorUser *User // site.site_creator_id_fkey - File *FileuploadFile // site.site_file_id_fkey - Parcel *Parcel // site.site_parcel_id_fkey + Leads LeadSlice // lead.lead_site_id_site_version_fkey + Pools PoolSlice // pool.pool_site_id_site_version_fkey + Residents ResidentSlice // resident.resident_site_id_site_version_fkey + Address *Address // site.site_address_id_fkey + CreatorUser *User // site.site_creator_id_fkey + File *FileuploadFile // site.site_file_id_fkey + Parcel *Parcel // site.site_parcel_id_fkey } func buildSiteColumns(alias string) siteColumns { @@ -642,14 +642,14 @@ func (o SiteSlice) ReloadAll(ctx context.Context, exec bob.Executor) error { return nil } -// ComplianceReportRequests starts a query for related objects on compliance_report_request -func (o *Site) ComplianceReportRequests(mods ...bob.Mod[*dialect.SelectQuery]) ComplianceReportRequestsQuery { - return ComplianceReportRequests.Query(append(mods, - sm.Where(ComplianceReportRequests.Columns.SiteID.EQ(psql.Arg(o.ID))), sm.Where(ComplianceReportRequests.Columns.SiteVersion.EQ(psql.Arg(o.Version))), +// Leads starts a query for related objects on lead +func (o *Site) Leads(mods ...bob.Mod[*dialect.SelectQuery]) LeadsQuery { + return Leads.Query(append(mods, + sm.Where(Leads.Columns.SiteID.EQ(psql.Arg(o.ID))), sm.Where(Leads.Columns.SiteVersion.EQ(psql.Arg(o.Version))), )...) } -func (os SiteSlice) ComplianceReportRequests(mods ...bob.Mod[*dialect.SelectQuery]) ComplianceReportRequestsQuery { +func (os SiteSlice) Leads(mods ...bob.Mod[*dialect.SelectQuery]) LeadsQuery { pkID := make(pgtypes.Array[int32], 0, len(os)) pkVersion := make(pgtypes.Array[int32], 0, len(os)) @@ -665,8 +665,8 @@ func (os SiteSlice) ComplianceReportRequests(mods ...bob.Mod[*dialect.SelectQuer psql.F("unnest", psql.Cast(psql.Arg(pkVersion), "integer[]")), )) - return ComplianceReportRequests.Query(append(mods, - sm.Where(psql.Group(ComplianceReportRequests.Columns.SiteID, ComplianceReportRequests.Columns.SiteVersion).OP("IN", PKArgExpr)), + return Leads.Query(append(mods, + sm.Where(psql.Group(Leads.Columns.SiteID, Leads.Columns.SiteVersion).OP("IN", PKArgExpr)), )...) } @@ -822,68 +822,68 @@ func (os SiteSlice) Parcel(mods ...bob.Mod[*dialect.SelectQuery]) ParcelsQuery { )...) } -func insertSiteComplianceReportRequests0(ctx context.Context, exec bob.Executor, complianceReportRequests1 []*ComplianceReportRequestSetter, site0 *Site) (ComplianceReportRequestSlice, error) { - for i := range complianceReportRequests1 { - complianceReportRequests1[i].SiteID = omit.From(site0.ID) - complianceReportRequests1[i].SiteVersion = omit.From(site0.Version) +func insertSiteLeads0(ctx context.Context, exec bob.Executor, leads1 []*LeadSetter, site0 *Site) (LeadSlice, error) { + for i := range leads1 { + leads1[i].SiteID = omitnull.From(site0.ID) + leads1[i].SiteVersion = omitnull.From(site0.Version) } - ret, err := ComplianceReportRequests.Insert(bob.ToMods(complianceReportRequests1...)).All(ctx, exec) + ret, err := Leads.Insert(bob.ToMods(leads1...)).All(ctx, exec) if err != nil { - return ret, fmt.Errorf("insertSiteComplianceReportRequests0: %w", err) + return ret, fmt.Errorf("insertSiteLeads0: %w", err) } return ret, nil } -func attachSiteComplianceReportRequests0(ctx context.Context, exec bob.Executor, count int, complianceReportRequests1 ComplianceReportRequestSlice, site0 *Site) (ComplianceReportRequestSlice, error) { - setter := &ComplianceReportRequestSetter{ - SiteID: omit.From(site0.ID), - SiteVersion: omit.From(site0.Version), +func attachSiteLeads0(ctx context.Context, exec bob.Executor, count int, leads1 LeadSlice, site0 *Site) (LeadSlice, error) { + setter := &LeadSetter{ + SiteID: omitnull.From(site0.ID), + SiteVersion: omitnull.From(site0.Version), } - err := complianceReportRequests1.UpdateAll(ctx, exec, *setter) + err := leads1.UpdateAll(ctx, exec, *setter) if err != nil { - return nil, fmt.Errorf("attachSiteComplianceReportRequests0: %w", err) + return nil, fmt.Errorf("attachSiteLeads0: %w", err) } - return complianceReportRequests1, nil + return leads1, nil } -func (site0 *Site) InsertComplianceReportRequests(ctx context.Context, exec bob.Executor, related ...*ComplianceReportRequestSetter) error { +func (site0 *Site) InsertLeads(ctx context.Context, exec bob.Executor, related ...*LeadSetter) error { if len(related) == 0 { return nil } var err error - complianceReportRequests1, err := insertSiteComplianceReportRequests0(ctx, exec, related, site0) + leads1, err := insertSiteLeads0(ctx, exec, related, site0) if err != nil { return err } - site0.R.ComplianceReportRequests = append(site0.R.ComplianceReportRequests, complianceReportRequests1...) + site0.R.Leads = append(site0.R.Leads, leads1...) - for _, rel := range complianceReportRequests1 { + for _, rel := range leads1 { rel.R.Site = site0 } return nil } -func (site0 *Site) AttachComplianceReportRequests(ctx context.Context, exec bob.Executor, related ...*ComplianceReportRequest) error { +func (site0 *Site) AttachLeads(ctx context.Context, exec bob.Executor, related ...*Lead) error { if len(related) == 0 { return nil } var err error - complianceReportRequests1 := ComplianceReportRequestSlice(related) + leads1 := LeadSlice(related) - _, err = attachSiteComplianceReportRequests0(ctx, exec, len(related), complianceReportRequests1, site0) + _, err = attachSiteLeads0(ctx, exec, len(related), leads1, site0) if err != nil { return err } - site0.R.ComplianceReportRequests = append(site0.R.ComplianceReportRequests, complianceReportRequests1...) + site0.R.Leads = append(site0.R.Leads, leads1...) for _, rel := range related { rel.R.Site = site0 @@ -1268,13 +1268,13 @@ func (o *Site) Preload(name string, retrieved any) error { } switch name { - case "ComplianceReportRequests": - rels, ok := retrieved.(ComplianceReportRequestSlice) + case "Leads": + rels, ok := retrieved.(LeadSlice) if !ok { return fmt.Errorf("site cannot load %T as %q", retrieved, name) } - o.R.ComplianceReportRequests = rels + o.R.Leads = rels for _, rel := range rels { if rel != nil { @@ -1428,18 +1428,18 @@ func buildSitePreloader() sitePreloader { } type siteThenLoader[Q orm.Loadable] struct { - ComplianceReportRequests func(...bob.Mod[*dialect.SelectQuery]) orm.Loader[Q] - Pools func(...bob.Mod[*dialect.SelectQuery]) orm.Loader[Q] - Residents func(...bob.Mod[*dialect.SelectQuery]) orm.Loader[Q] - Address func(...bob.Mod[*dialect.SelectQuery]) orm.Loader[Q] - CreatorUser func(...bob.Mod[*dialect.SelectQuery]) orm.Loader[Q] - File func(...bob.Mod[*dialect.SelectQuery]) orm.Loader[Q] - Parcel func(...bob.Mod[*dialect.SelectQuery]) orm.Loader[Q] + Leads func(...bob.Mod[*dialect.SelectQuery]) orm.Loader[Q] + Pools func(...bob.Mod[*dialect.SelectQuery]) orm.Loader[Q] + Residents func(...bob.Mod[*dialect.SelectQuery]) orm.Loader[Q] + Address func(...bob.Mod[*dialect.SelectQuery]) orm.Loader[Q] + CreatorUser func(...bob.Mod[*dialect.SelectQuery]) orm.Loader[Q] + File func(...bob.Mod[*dialect.SelectQuery]) orm.Loader[Q] + Parcel func(...bob.Mod[*dialect.SelectQuery]) orm.Loader[Q] } func buildSiteThenLoader[Q orm.Loadable]() siteThenLoader[Q] { - type ComplianceReportRequestsLoadInterface interface { - LoadComplianceReportRequests(context.Context, bob.Executor, ...bob.Mod[*dialect.SelectQuery]) error + type LeadsLoadInterface interface { + LoadLeads(context.Context, bob.Executor, ...bob.Mod[*dialect.SelectQuery]) error } type PoolsLoadInterface interface { LoadPools(context.Context, bob.Executor, ...bob.Mod[*dialect.SelectQuery]) error @@ -1461,10 +1461,10 @@ func buildSiteThenLoader[Q orm.Loadable]() siteThenLoader[Q] { } return siteThenLoader[Q]{ - ComplianceReportRequests: thenLoadBuilder[Q]( - "ComplianceReportRequests", - func(ctx context.Context, exec bob.Executor, retrieved ComplianceReportRequestsLoadInterface, mods ...bob.Mod[*dialect.SelectQuery]) error { - return retrieved.LoadComplianceReportRequests(ctx, exec, mods...) + Leads: thenLoadBuilder[Q]( + "Leads", + func(ctx context.Context, exec bob.Executor, retrieved LeadsLoadInterface, mods ...bob.Mod[*dialect.SelectQuery]) error { + return retrieved.LoadLeads(ctx, exec, mods...) }, ), Pools: thenLoadBuilder[Q]( @@ -1506,16 +1506,16 @@ func buildSiteThenLoader[Q orm.Loadable]() siteThenLoader[Q] { } } -// LoadComplianceReportRequests loads the site's ComplianceReportRequests into the .R struct -func (o *Site) LoadComplianceReportRequests(ctx context.Context, exec bob.Executor, mods ...bob.Mod[*dialect.SelectQuery]) error { +// LoadLeads loads the site's Leads into the .R struct +func (o *Site) LoadLeads(ctx context.Context, exec bob.Executor, mods ...bob.Mod[*dialect.SelectQuery]) error { if o == nil { return nil } // Reset the relationship - o.R.ComplianceReportRequests = nil + o.R.Leads = nil - related, err := o.ComplianceReportRequests(mods...).All(ctx, exec) + related, err := o.Leads(mods...).All(ctx, exec) if err != nil { return err } @@ -1524,17 +1524,17 @@ func (o *Site) LoadComplianceReportRequests(ctx context.Context, exec bob.Execut rel.R.Site = o } - o.R.ComplianceReportRequests = related + o.R.Leads = related return nil } -// LoadComplianceReportRequests loads the site's ComplianceReportRequests into the .R struct -func (os SiteSlice) LoadComplianceReportRequests(ctx context.Context, exec bob.Executor, mods ...bob.Mod[*dialect.SelectQuery]) error { +// LoadLeads loads the site's Leads into the .R struct +func (os SiteSlice) LoadLeads(ctx context.Context, exec bob.Executor, mods ...bob.Mod[*dialect.SelectQuery]) error { if len(os) == 0 { return nil } - complianceReportRequests, err := os.ComplianceReportRequests(mods...).All(ctx, exec) + leads, err := os.Leads(mods...).All(ctx, exec) if err != nil { return err } @@ -1544,7 +1544,7 @@ func (os SiteSlice) LoadComplianceReportRequests(ctx context.Context, exec bob.E continue } - o.R.ComplianceReportRequests = nil + o.R.Leads = nil } for _, o := range os { @@ -1552,19 +1552,25 @@ func (os SiteSlice) LoadComplianceReportRequests(ctx context.Context, exec bob.E continue } - for _, rel := range complianceReportRequests { + for _, rel := range leads { - if !(o.ID == rel.SiteID) { + if !rel.SiteID.IsValue() { + continue + } + if !(rel.SiteID.IsValue() && o.ID == rel.SiteID.MustGet()) { continue } - if !(o.Version == rel.SiteVersion) { + if !rel.SiteVersion.IsValue() { + continue + } + if !(rel.SiteVersion.IsValue() && o.Version == rel.SiteVersion.MustGet()) { continue } rel.R.Site = o - o.R.ComplianceReportRequests = append(o.R.ComplianceReportRequests, rel) + o.R.Leads = append(o.R.Leads, rel) } } @@ -1914,9 +1920,9 @@ func (os SiteSlice) LoadParcel(ctx context.Context, exec bob.Executor, mods ...b // siteC is where relationship counts are stored. type siteC struct { - ComplianceReportRequests *int64 - Pools *int64 - Residents *int64 + Leads *int64 + Pools *int64 + Residents *int64 } // PreloadCount sets a count in the C struct by name @@ -1926,8 +1932,8 @@ func (o *Site) PreloadCount(name string, count int64) error { } switch name { - case "ComplianceReportRequests": - o.C.ComplianceReportRequests = &count + case "Leads": + o.C.Leads = &count case "Pools": o.C.Pools = &count case "Residents": @@ -1937,15 +1943,15 @@ func (o *Site) PreloadCount(name string, count int64) error { } type siteCountPreloader struct { - ComplianceReportRequests func(...bob.Mod[*dialect.SelectQuery]) psql.Preloader - Pools func(...bob.Mod[*dialect.SelectQuery]) psql.Preloader - Residents func(...bob.Mod[*dialect.SelectQuery]) psql.Preloader + Leads func(...bob.Mod[*dialect.SelectQuery]) psql.Preloader + Pools func(...bob.Mod[*dialect.SelectQuery]) psql.Preloader + Residents func(...bob.Mod[*dialect.SelectQuery]) psql.Preloader } func buildSiteCountPreloader() siteCountPreloader { return siteCountPreloader{ - ComplianceReportRequests: func(mods ...bob.Mod[*dialect.SelectQuery]) psql.Preloader { - return countPreloader[*Site]("ComplianceReportRequests", func(parent string) bob.Expression { + Leads: func(mods ...bob.Mod[*dialect.SelectQuery]) psql.Preloader { + return countPreloader[*Site]("Leads", func(parent string) bob.Expression { // Build a correlated subquery: (SELECT COUNT(*) FROM related WHERE fk = parent.pk) if parent == "" { parent = Sites.Alias() @@ -1954,9 +1960,9 @@ func buildSiteCountPreloader() siteCountPreloader { subqueryMods := []bob.Mod[*dialect.SelectQuery]{ sm.Columns(psql.Raw("count(*)")), - sm.From(ComplianceReportRequests.Name()), - sm.Where(psql.Quote(ComplianceReportRequests.Alias(), "site_id").EQ(psql.Quote(parent, "id"))), - sm.Where(psql.Quote(ComplianceReportRequests.Alias(), "site_version").EQ(psql.Quote(parent, "version"))), + sm.From(Leads.Name()), + sm.Where(psql.Quote(Leads.Alias(), "site_id").EQ(psql.Quote(parent, "id"))), + sm.Where(psql.Quote(Leads.Alias(), "site_version").EQ(psql.Quote(parent, "version"))), } subqueryMods = append(subqueryMods, mods...) return psql.Group(psql.Select(subqueryMods...).Expression) @@ -2002,14 +2008,14 @@ func buildSiteCountPreloader() siteCountPreloader { } type siteCountThenLoader[Q orm.Loadable] struct { - ComplianceReportRequests func(...bob.Mod[*dialect.SelectQuery]) orm.Loader[Q] - Pools func(...bob.Mod[*dialect.SelectQuery]) orm.Loader[Q] - Residents func(...bob.Mod[*dialect.SelectQuery]) orm.Loader[Q] + Leads func(...bob.Mod[*dialect.SelectQuery]) orm.Loader[Q] + Pools func(...bob.Mod[*dialect.SelectQuery]) orm.Loader[Q] + Residents func(...bob.Mod[*dialect.SelectQuery]) orm.Loader[Q] } func buildSiteCountThenLoader[Q orm.Loadable]() siteCountThenLoader[Q] { - type ComplianceReportRequestsCountInterface interface { - LoadCountComplianceReportRequests(context.Context, bob.Executor, ...bob.Mod[*dialect.SelectQuery]) error + type LeadsCountInterface interface { + LoadCountLeads(context.Context, bob.Executor, ...bob.Mod[*dialect.SelectQuery]) error } type PoolsCountInterface interface { LoadCountPools(context.Context, bob.Executor, ...bob.Mod[*dialect.SelectQuery]) error @@ -2019,10 +2025,10 @@ func buildSiteCountThenLoader[Q orm.Loadable]() siteCountThenLoader[Q] { } return siteCountThenLoader[Q]{ - ComplianceReportRequests: countThenLoadBuilder[Q]( - "ComplianceReportRequests", - func(ctx context.Context, exec bob.Executor, retrieved ComplianceReportRequestsCountInterface, mods ...bob.Mod[*dialect.SelectQuery]) error { - return retrieved.LoadCountComplianceReportRequests(ctx, exec, mods...) + Leads: countThenLoadBuilder[Q]( + "Leads", + func(ctx context.Context, exec bob.Executor, retrieved LeadsCountInterface, mods ...bob.Mod[*dialect.SelectQuery]) error { + return retrieved.LoadCountLeads(ctx, exec, mods...) }, ), Pools: countThenLoadBuilder[Q]( @@ -2040,29 +2046,29 @@ func buildSiteCountThenLoader[Q orm.Loadable]() siteCountThenLoader[Q] { } } -// LoadCountComplianceReportRequests loads the count of ComplianceReportRequests into the C struct -func (o *Site) LoadCountComplianceReportRequests(ctx context.Context, exec bob.Executor, mods ...bob.Mod[*dialect.SelectQuery]) error { +// LoadCountLeads loads the count of Leads into the C struct +func (o *Site) LoadCountLeads(ctx context.Context, exec bob.Executor, mods ...bob.Mod[*dialect.SelectQuery]) error { if o == nil { return nil } - count, err := o.ComplianceReportRequests(mods...).Count(ctx, exec) + count, err := o.Leads(mods...).Count(ctx, exec) if err != nil { return err } - o.C.ComplianceReportRequests = &count + o.C.Leads = &count return nil } -// LoadCountComplianceReportRequests loads the count of ComplianceReportRequests for a slice -func (os SiteSlice) LoadCountComplianceReportRequests(ctx context.Context, exec bob.Executor, mods ...bob.Mod[*dialect.SelectQuery]) error { +// LoadCountLeads loads the count of Leads for a slice +func (os SiteSlice) LoadCountLeads(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.LoadCountComplianceReportRequests(ctx, exec, mods...); err != nil { + if err := o.LoadCountLeads(ctx, exec, mods...); err != nil { return err } } @@ -2131,14 +2137,14 @@ func (os SiteSlice) LoadCountResidents(ctx context.Context, exec bob.Executor, m } type siteJoins[Q dialect.Joinable] struct { - typ string - ComplianceReportRequests modAs[Q, complianceReportRequestColumns] - Pools modAs[Q, poolColumns] - Residents modAs[Q, residentColumns] - Address modAs[Q, addressColumns] - CreatorUser modAs[Q, userColumns] - File modAs[Q, fileuploadFileColumns] - Parcel modAs[Q, parcelColumns] + typ string + Leads modAs[Q, leadColumns] + Pools modAs[Q, poolColumns] + Residents modAs[Q, residentColumns] + Address modAs[Q, addressColumns] + CreatorUser modAs[Q, userColumns] + File modAs[Q, fileuploadFileColumns] + Parcel modAs[Q, parcelColumns] } func (j siteJoins[Q]) aliasedAs(alias string) siteJoins[Q] { @@ -2148,13 +2154,13 @@ func (j siteJoins[Q]) aliasedAs(alias string) siteJoins[Q] { func buildSiteJoins[Q dialect.Joinable](cols siteColumns, typ string) siteJoins[Q] { return siteJoins[Q]{ typ: typ, - ComplianceReportRequests: modAs[Q, complianceReportRequestColumns]{ - c: ComplianceReportRequests.Columns, - f: func(to complianceReportRequestColumns) bob.Mod[Q] { + Leads: modAs[Q, leadColumns]{ + c: Leads.Columns, + f: func(to leadColumns) bob.Mod[Q] { mods := make(mods.QueryMods[Q], 0, 1) { - mods = append(mods, dialect.Join[Q](typ, ComplianceReportRequests.Name().As(to.Alias())).On( + mods = append(mods, dialect.Join[Q](typ, Leads.Name().As(to.Alias())).On( to.SiteID.EQ(cols.ID), to.SiteVersion.EQ(cols.Version), )) } diff --git a/db/models/user_.bob.go b/db/models/user_.bob.go index 40e9a697..1408a10b 100644 --- a/db/models/user_.bob.go +++ b/db/models/user_.bob.go @@ -61,8 +61,10 @@ type userR struct { UserOauthTokens ArcgisOauthTokenSlice // arcgis.oauth_token.oauth_token_user_id_fkey PublicUserUser ArcgisUserSlice // arcgis.user_.user__public_user_id_fkey CreatorComplianceReportRequests ComplianceReportRequestSlice // compliance_report_request.compliance_report_request_creator_fkey + CommitterFiles FileuploadFileSlice // fileupload.file.file_committer_fkey CreatorFiles FileuploadFileSlice // fileupload.file.file_creator_id_fkey FileuploadPool FileuploadPoolSlice // fileupload.pool.pool_creator_id_fkey + CreatorLeads LeadSlice // lead.lead_creator_fkey CreatorNoteAudios NoteAudioSlice // note_audio.note_audio_creator_id_fkey DeletorNoteAudios NoteAudioSlice // note_audio.note_audio_deletor_id_fkey CreatorNoteImages NoteImageSlice // note_image.note_image_creator_id_fkey @@ -714,6 +716,30 @@ func (os UserSlice) CreatorComplianceReportRequests(mods ...bob.Mod[*dialect.Sel )...) } +// CommitterFiles starts a query for related objects on fileupload.file +func (o *User) CommitterFiles(mods ...bob.Mod[*dialect.SelectQuery]) FileuploadFilesQuery { + return FileuploadFiles.Query(append(mods, + sm.Where(FileuploadFiles.Columns.Committer.EQ(psql.Arg(o.ID))), + )...) +} + +func (os UserSlice) CommitterFiles(mods ...bob.Mod[*dialect.SelectQuery]) FileuploadFilesQuery { + pkID := make(pgtypes.Array[int32], 0, len(os)) + for _, o := range os { + if o == nil { + continue + } + pkID = append(pkID, o.ID) + } + PKArgExpr := psql.Select(sm.Columns( + psql.F("unnest", psql.Cast(psql.Arg(pkID), "integer[]")), + )) + + return FileuploadFiles.Query(append(mods, + sm.Where(psql.Group(FileuploadFiles.Columns.Committer).OP("IN", PKArgExpr)), + )...) +} + // CreatorFiles starts a query for related objects on fileupload.file func (o *User) CreatorFiles(mods ...bob.Mod[*dialect.SelectQuery]) FileuploadFilesQuery { return FileuploadFiles.Query(append(mods, @@ -762,6 +788,30 @@ func (os UserSlice) FileuploadPool(mods ...bob.Mod[*dialect.SelectQuery]) Fileup )...) } +// CreatorLeads starts a query for related objects on lead +func (o *User) CreatorLeads(mods ...bob.Mod[*dialect.SelectQuery]) LeadsQuery { + return Leads.Query(append(mods, + sm.Where(Leads.Columns.Creator.EQ(psql.Arg(o.ID))), + )...) +} + +func (os UserSlice) CreatorLeads(mods ...bob.Mod[*dialect.SelectQuery]) LeadsQuery { + pkID := make(pgtypes.Array[int32], 0, len(os)) + for _, o := range os { + if o == nil { + continue + } + pkID = append(pkID, o.ID) + } + PKArgExpr := psql.Select(sm.Columns( + psql.F("unnest", psql.Cast(psql.Arg(pkID), "integer[]")), + )) + + return Leads.Query(append(mods, + sm.Where(psql.Group(Leads.Columns.Creator).OP("IN", PKArgExpr)), + )...) +} + // CreatorNoteAudios starts a query for related objects on note_audio func (o *User) CreatorNoteAudios(mods ...bob.Mod[*dialect.SelectQuery]) NoteAudiosQuery { return NoteAudios.Query(append(mods, @@ -1230,6 +1280,74 @@ func (user0 *User) AttachCreatorComplianceReportRequests(ctx context.Context, ex return nil } +func insertUserCommitterFiles0(ctx context.Context, exec bob.Executor, fileuploadFiles1 []*FileuploadFileSetter, user0 *User) (FileuploadFileSlice, error) { + for i := range fileuploadFiles1 { + fileuploadFiles1[i].Committer = omitnull.From(user0.ID) + } + + ret, err := FileuploadFiles.Insert(bob.ToMods(fileuploadFiles1...)).All(ctx, exec) + if err != nil { + return ret, fmt.Errorf("insertUserCommitterFiles0: %w", err) + } + + return ret, nil +} + +func attachUserCommitterFiles0(ctx context.Context, exec bob.Executor, count int, fileuploadFiles1 FileuploadFileSlice, user0 *User) (FileuploadFileSlice, error) { + setter := &FileuploadFileSetter{ + Committer: omitnull.From(user0.ID), + } + + err := fileuploadFiles1.UpdateAll(ctx, exec, *setter) + if err != nil { + return nil, fmt.Errorf("attachUserCommitterFiles0: %w", err) + } + + return fileuploadFiles1, nil +} + +func (user0 *User) InsertCommitterFiles(ctx context.Context, exec bob.Executor, related ...*FileuploadFileSetter) error { + if len(related) == 0 { + return nil + } + + var err error + + fileuploadFiles1, err := insertUserCommitterFiles0(ctx, exec, related, user0) + if err != nil { + return err + } + + user0.R.CommitterFiles = append(user0.R.CommitterFiles, fileuploadFiles1...) + + for _, rel := range fileuploadFiles1 { + rel.R.CommitterUser = user0 + } + return nil +} + +func (user0 *User) AttachCommitterFiles(ctx context.Context, exec bob.Executor, related ...*FileuploadFile) error { + if len(related) == 0 { + return nil + } + + var err error + fileuploadFiles1 := FileuploadFileSlice(related) + + _, err = attachUserCommitterFiles0(ctx, exec, len(related), fileuploadFiles1, user0) + if err != nil { + return err + } + + user0.R.CommitterFiles = append(user0.R.CommitterFiles, fileuploadFiles1...) + + for _, rel := range related { + rel.R.CommitterUser = user0 + } + + return nil +} + func insertUserCreatorFiles0(ctx context.Context, exec bob.Executor, fileuploadFiles1 []*FileuploadFileSetter, user0 *User) (FileuploadFileSlice, error) { for i := range fileuploadFiles1 { fileuploadFiles1[i].CreatorID = omit.From(user0.ID) @@ -1366,6 +1484,74 @@ func (user0 *User) AttachFileuploadPool(ctx context.Context, exec bob.Executor, return nil } +func insertUserCreatorLeads0(ctx context.Context, exec bob.Executor, leads1 []*LeadSetter, user0 *User) (LeadSlice, error) { + for i := range leads1 { + leads1[i].Creator = omit.From(user0.ID) + } + + ret, err := Leads.Insert(bob.ToMods(leads1...)).All(ctx, exec) + if err != nil { + return ret, fmt.Errorf("insertUserCreatorLeads0: %w", err) + } + + return ret, nil +} + +func attachUserCreatorLeads0(ctx context.Context, exec bob.Executor, count int, leads1 LeadSlice, user0 *User) (LeadSlice, error) { + setter := &LeadSetter{ + Creator: omit.From(user0.ID), + } + + err := leads1.UpdateAll(ctx, exec, *setter) + if err != nil { + return nil, fmt.Errorf("attachUserCreatorLeads0: %w", err) + } + + return leads1, nil +} + +func (user0 *User) InsertCreatorLeads(ctx context.Context, exec bob.Executor, related ...*LeadSetter) error { + if len(related) == 0 { + return nil + } + + var err error + + leads1, err := insertUserCreatorLeads0(ctx, exec, related, user0) + if err != nil { + return err + } + + user0.R.CreatorLeads = append(user0.R.CreatorLeads, leads1...) + + for _, rel := range leads1 { + rel.R.CreatorUser = user0 + } + return nil +} + +func (user0 *User) AttachCreatorLeads(ctx context.Context, exec bob.Executor, related ...*Lead) error { + if len(related) == 0 { + return nil + } + + var err error + leads1 := LeadSlice(related) + + _, err = attachUserCreatorLeads0(ctx, exec, len(related), leads1, user0) + if err != nil { + return err + } + + user0.R.CreatorLeads = append(user0.R.CreatorLeads, leads1...) + + for _, rel := range related { + rel.R.CreatorUser = user0 + } + + return nil +} + func insertUserCreatorNoteAudios0(ctx context.Context, exec bob.Executor, noteAudios1 []*NoteAudioSetter, user0 *User) (NoteAudioSlice, error) { for i := range noteAudios1 { noteAudios1[i].CreatorID = omit.From(user0.ID) @@ -2180,6 +2366,20 @@ func (o *User) Preload(name string, retrieved any) error { } } return nil + case "CommitterFiles": + rels, ok := retrieved.(FileuploadFileSlice) + if !ok { + return fmt.Errorf("user cannot load %T as %q", retrieved, name) + } + + o.R.CommitterFiles = rels + + for _, rel := range rels { + if rel != nil { + rel.R.CommitterUser = o + } + } + return nil case "CreatorFiles": rels, ok := retrieved.(FileuploadFileSlice) if !ok { @@ -2202,6 +2402,20 @@ func (o *User) Preload(name string, retrieved any) error { o.R.FileuploadPool = rels + for _, rel := range rels { + if rel != nil { + rel.R.CreatorUser = o + } + } + return nil + case "CreatorLeads": + rels, ok := retrieved.(LeadSlice) + if !ok { + return fmt.Errorf("user cannot load %T as %q", retrieved, name) + } + + o.R.CreatorLeads = rels + for _, rel := range rels { if rel != nil { rel.R.CreatorUser = o @@ -2391,8 +2605,10 @@ type userThenLoader[Q orm.Loadable] struct { UserOauthTokens func(...bob.Mod[*dialect.SelectQuery]) orm.Loader[Q] PublicUserUser func(...bob.Mod[*dialect.SelectQuery]) orm.Loader[Q] CreatorComplianceReportRequests func(...bob.Mod[*dialect.SelectQuery]) orm.Loader[Q] + CommitterFiles func(...bob.Mod[*dialect.SelectQuery]) orm.Loader[Q] CreatorFiles func(...bob.Mod[*dialect.SelectQuery]) orm.Loader[Q] FileuploadPool func(...bob.Mod[*dialect.SelectQuery]) orm.Loader[Q] + CreatorLeads func(...bob.Mod[*dialect.SelectQuery]) orm.Loader[Q] CreatorNoteAudios func(...bob.Mod[*dialect.SelectQuery]) orm.Loader[Q] DeletorNoteAudios func(...bob.Mod[*dialect.SelectQuery]) orm.Loader[Q] CreatorNoteImages func(...bob.Mod[*dialect.SelectQuery]) orm.Loader[Q] @@ -2416,12 +2632,18 @@ func buildUserThenLoader[Q orm.Loadable]() userThenLoader[Q] { type CreatorComplianceReportRequestsLoadInterface interface { LoadCreatorComplianceReportRequests(context.Context, bob.Executor, ...bob.Mod[*dialect.SelectQuery]) error } + type CommitterFilesLoadInterface interface { + LoadCommitterFiles(context.Context, bob.Executor, ...bob.Mod[*dialect.SelectQuery]) error + } type CreatorFilesLoadInterface interface { LoadCreatorFiles(context.Context, bob.Executor, ...bob.Mod[*dialect.SelectQuery]) error } type FileuploadPoolLoadInterface interface { LoadFileuploadPool(context.Context, bob.Executor, ...bob.Mod[*dialect.SelectQuery]) error } + type CreatorLeadsLoadInterface interface { + LoadCreatorLeads(context.Context, bob.Executor, ...bob.Mod[*dialect.SelectQuery]) error + } type CreatorNoteAudiosLoadInterface interface { LoadCreatorNoteAudios(context.Context, bob.Executor, ...bob.Mod[*dialect.SelectQuery]) error } @@ -2475,6 +2697,12 @@ func buildUserThenLoader[Q orm.Loadable]() userThenLoader[Q] { return retrieved.LoadCreatorComplianceReportRequests(ctx, exec, mods...) }, ), + CommitterFiles: thenLoadBuilder[Q]( + "CommitterFiles", + func(ctx context.Context, exec bob.Executor, retrieved CommitterFilesLoadInterface, mods ...bob.Mod[*dialect.SelectQuery]) error { + return retrieved.LoadCommitterFiles(ctx, exec, mods...) + }, + ), CreatorFiles: thenLoadBuilder[Q]( "CreatorFiles", func(ctx context.Context, exec bob.Executor, retrieved CreatorFilesLoadInterface, mods ...bob.Mod[*dialect.SelectQuery]) error { @@ -2487,6 +2715,12 @@ func buildUserThenLoader[Q orm.Loadable]() userThenLoader[Q] { return retrieved.LoadFileuploadPool(ctx, exec, mods...) }, ), + CreatorLeads: thenLoadBuilder[Q]( + "CreatorLeads", + func(ctx context.Context, exec bob.Executor, retrieved CreatorLeadsLoadInterface, mods ...bob.Mod[*dialect.SelectQuery]) error { + return retrieved.LoadCreatorLeads(ctx, exec, mods...) + }, + ), CreatorNoteAudios: thenLoadBuilder[Q]( "CreatorNoteAudios", func(ctx context.Context, exec bob.Executor, retrieved CreatorNoteAudiosLoadInterface, mods ...bob.Mod[*dialect.SelectQuery]) error { @@ -2739,6 +2973,70 @@ func (os UserSlice) LoadCreatorComplianceReportRequests(ctx context.Context, exe return nil } +// LoadCommitterFiles loads the user's CommitterFiles into the .R struct +func (o *User) LoadCommitterFiles(ctx context.Context, exec bob.Executor, mods ...bob.Mod[*dialect.SelectQuery]) error { + if o == nil { + return nil + } + + // Reset the relationship + o.R.CommitterFiles = nil + + related, err := o.CommitterFiles(mods...).All(ctx, exec) + if err != nil { + return err + } + + for _, rel := range related { + rel.R.CommitterUser = o + } + + o.R.CommitterFiles = related + return nil +} + +// LoadCommitterFiles loads the user's CommitterFiles into the .R struct +func (os UserSlice) LoadCommitterFiles(ctx context.Context, exec bob.Executor, mods ...bob.Mod[*dialect.SelectQuery]) error { + if len(os) == 0 { + return nil + } + + fileuploadFiles, err := os.CommitterFiles(mods...).All(ctx, exec) + if err != nil { + return err + } + + for _, o := range os { + if o == nil { + continue + } + + o.R.CommitterFiles = nil + } + + for _, o := range os { + if o == nil { + continue + } + + for _, rel := range fileuploadFiles { + + if !rel.Committer.IsValue() { + continue + } + if !(rel.Committer.IsValue() && o.ID == rel.Committer.MustGet()) { + continue + } + + rel.R.CommitterUser = o + + o.R.CommitterFiles = append(o.R.CommitterFiles, rel) + } + } + + return nil +} + // LoadCreatorFiles loads the user's CreatorFiles into the .R struct func (o *User) LoadCreatorFiles(ctx context.Context, exec bob.Executor, mods ...bob.Mod[*dialect.SelectQuery]) error { if o == nil { @@ -2861,6 +3159,67 @@ func (os UserSlice) LoadFileuploadPool(ctx context.Context, exec bob.Executor, m return nil } +// LoadCreatorLeads loads the user's CreatorLeads into the .R struct +func (o *User) LoadCreatorLeads(ctx context.Context, exec bob.Executor, mods ...bob.Mod[*dialect.SelectQuery]) error { + if o == nil { + return nil + } + + // Reset the relationship + o.R.CreatorLeads = nil + + related, err := o.CreatorLeads(mods...).All(ctx, exec) + if err != nil { + return err + } + + for _, rel := range related { + rel.R.CreatorUser = o + } + + o.R.CreatorLeads = related + return nil +} + +// LoadCreatorLeads loads the user's CreatorLeads into the .R struct +func (os UserSlice) LoadCreatorLeads(ctx context.Context, exec bob.Executor, mods ...bob.Mod[*dialect.SelectQuery]) error { + if len(os) == 0 { + return nil + } + + leads, err := os.CreatorLeads(mods...).All(ctx, exec) + if err != nil { + return err + } + + for _, o := range os { + if o == nil { + continue + } + + o.R.CreatorLeads = nil + } + + for _, o := range os { + if o == nil { + continue + } + + for _, rel := range leads { + + if !(o.ID == rel.Creator) { + continue + } + + rel.R.CreatorUser = o + + o.R.CreatorLeads = append(o.R.CreatorLeads, rel) + } + } + + return nil +} + // LoadCreatorNoteAudios loads the user's CreatorNoteAudios into the .R struct func (o *User) LoadCreatorNoteAudios(ctx context.Context, exec bob.Executor, mods ...bob.Mod[*dialect.SelectQuery]) error { if o == nil { @@ -3537,8 +3896,10 @@ type userC struct { UserOauthTokens *int64 PublicUserUser *int64 CreatorComplianceReportRequests *int64 + CommitterFiles *int64 CreatorFiles *int64 FileuploadPool *int64 + CreatorLeads *int64 CreatorNoteAudios *int64 DeletorNoteAudios *int64 CreatorNoteImages *int64 @@ -3564,10 +3925,14 @@ func (o *User) PreloadCount(name string, count int64) error { o.C.PublicUserUser = &count case "CreatorComplianceReportRequests": o.C.CreatorComplianceReportRequests = &count + case "CommitterFiles": + o.C.CommitterFiles = &count case "CreatorFiles": o.C.CreatorFiles = &count case "FileuploadPool": o.C.FileuploadPool = &count + case "CreatorLeads": + o.C.CreatorLeads = &count case "CreatorNoteAudios": o.C.CreatorNoteAudios = &count case "DeletorNoteAudios": @@ -3596,8 +3961,10 @@ type userCountPreloader struct { UserOauthTokens func(...bob.Mod[*dialect.SelectQuery]) psql.Preloader PublicUserUser func(...bob.Mod[*dialect.SelectQuery]) psql.Preloader CreatorComplianceReportRequests func(...bob.Mod[*dialect.SelectQuery]) psql.Preloader + CommitterFiles func(...bob.Mod[*dialect.SelectQuery]) psql.Preloader CreatorFiles func(...bob.Mod[*dialect.SelectQuery]) psql.Preloader FileuploadPool func(...bob.Mod[*dialect.SelectQuery]) psql.Preloader + CreatorLeads func(...bob.Mod[*dialect.SelectQuery]) psql.Preloader CreatorNoteAudios func(...bob.Mod[*dialect.SelectQuery]) psql.Preloader DeletorNoteAudios func(...bob.Mod[*dialect.SelectQuery]) psql.Preloader CreatorNoteImages func(...bob.Mod[*dialect.SelectQuery]) psql.Preloader @@ -3663,6 +4030,23 @@ func buildUserCountPreloader() userCountPreloader { return psql.Group(psql.Select(subqueryMods...).Expression) }) }, + CommitterFiles: func(mods ...bob.Mod[*dialect.SelectQuery]) psql.Preloader { + return countPreloader[*User]("CommitterFiles", func(parent string) bob.Expression { + // Build a correlated subquery: (SELECT COUNT(*) FROM related WHERE fk = parent.pk) + if parent == "" { + parent = Users.Alias() + } + + subqueryMods := []bob.Mod[*dialect.SelectQuery]{ + sm.Columns(psql.Raw("count(*)")), + + sm.From(FileuploadFiles.Name()), + sm.Where(psql.Quote(FileuploadFiles.Alias(), "committer").EQ(psql.Quote(parent, "id"))), + } + subqueryMods = append(subqueryMods, mods...) + return psql.Group(psql.Select(subqueryMods...).Expression) + }) + }, CreatorFiles: func(mods ...bob.Mod[*dialect.SelectQuery]) psql.Preloader { return countPreloader[*User]("CreatorFiles", func(parent string) bob.Expression { // Build a correlated subquery: (SELECT COUNT(*) FROM related WHERE fk = parent.pk) @@ -3697,6 +4081,23 @@ func buildUserCountPreloader() userCountPreloader { return psql.Group(psql.Select(subqueryMods...).Expression) }) }, + CreatorLeads: func(mods ...bob.Mod[*dialect.SelectQuery]) psql.Preloader { + return countPreloader[*User]("CreatorLeads", func(parent string) bob.Expression { + // Build a correlated subquery: (SELECT COUNT(*) FROM related WHERE fk = parent.pk) + if parent == "" { + parent = Users.Alias() + } + + subqueryMods := []bob.Mod[*dialect.SelectQuery]{ + sm.Columns(psql.Raw("count(*)")), + + sm.From(Leads.Name()), + sm.Where(psql.Quote(Leads.Alias(), "creator").EQ(psql.Quote(parent, "id"))), + } + subqueryMods = append(subqueryMods, mods...) + return psql.Group(psql.Select(subqueryMods...).Expression) + }) + }, CreatorNoteAudios: func(mods ...bob.Mod[*dialect.SelectQuery]) psql.Preloader { return countPreloader[*User]("CreatorNoteAudios", func(parent string) bob.Expression { // Build a correlated subquery: (SELECT COUNT(*) FROM related WHERE fk = parent.pk) @@ -3874,8 +4275,10 @@ type userCountThenLoader[Q orm.Loadable] struct { UserOauthTokens func(...bob.Mod[*dialect.SelectQuery]) orm.Loader[Q] PublicUserUser func(...bob.Mod[*dialect.SelectQuery]) orm.Loader[Q] CreatorComplianceReportRequests func(...bob.Mod[*dialect.SelectQuery]) orm.Loader[Q] + CommitterFiles func(...bob.Mod[*dialect.SelectQuery]) orm.Loader[Q] CreatorFiles func(...bob.Mod[*dialect.SelectQuery]) orm.Loader[Q] FileuploadPool func(...bob.Mod[*dialect.SelectQuery]) orm.Loader[Q] + CreatorLeads func(...bob.Mod[*dialect.SelectQuery]) orm.Loader[Q] CreatorNoteAudios func(...bob.Mod[*dialect.SelectQuery]) orm.Loader[Q] DeletorNoteAudios func(...bob.Mod[*dialect.SelectQuery]) orm.Loader[Q] CreatorNoteImages func(...bob.Mod[*dialect.SelectQuery]) orm.Loader[Q] @@ -3898,12 +4301,18 @@ func buildUserCountThenLoader[Q orm.Loadable]() userCountThenLoader[Q] { type CreatorComplianceReportRequestsCountInterface interface { LoadCountCreatorComplianceReportRequests(context.Context, bob.Executor, ...bob.Mod[*dialect.SelectQuery]) error } + type CommitterFilesCountInterface interface { + LoadCountCommitterFiles(context.Context, bob.Executor, ...bob.Mod[*dialect.SelectQuery]) error + } type CreatorFilesCountInterface interface { LoadCountCreatorFiles(context.Context, bob.Executor, ...bob.Mod[*dialect.SelectQuery]) error } type FileuploadPoolCountInterface interface { LoadCountFileuploadPool(context.Context, bob.Executor, ...bob.Mod[*dialect.SelectQuery]) error } + type CreatorLeadsCountInterface interface { + LoadCountCreatorLeads(context.Context, bob.Executor, ...bob.Mod[*dialect.SelectQuery]) error + } type CreatorNoteAudiosCountInterface interface { LoadCountCreatorNoteAudios(context.Context, bob.Executor, ...bob.Mod[*dialect.SelectQuery]) error } @@ -3954,6 +4363,12 @@ func buildUserCountThenLoader[Q orm.Loadable]() userCountThenLoader[Q] { return retrieved.LoadCountCreatorComplianceReportRequests(ctx, exec, mods...) }, ), + CommitterFiles: countThenLoadBuilder[Q]( + "CommitterFiles", + func(ctx context.Context, exec bob.Executor, retrieved CommitterFilesCountInterface, mods ...bob.Mod[*dialect.SelectQuery]) error { + return retrieved.LoadCountCommitterFiles(ctx, exec, mods...) + }, + ), CreatorFiles: countThenLoadBuilder[Q]( "CreatorFiles", func(ctx context.Context, exec bob.Executor, retrieved CreatorFilesCountInterface, mods ...bob.Mod[*dialect.SelectQuery]) error { @@ -3966,6 +4381,12 @@ func buildUserCountThenLoader[Q orm.Loadable]() userCountThenLoader[Q] { return retrieved.LoadCountFileuploadPool(ctx, exec, mods...) }, ), + CreatorLeads: countThenLoadBuilder[Q]( + "CreatorLeads", + func(ctx context.Context, exec bob.Executor, retrieved CreatorLeadsCountInterface, mods ...bob.Mod[*dialect.SelectQuery]) error { + return retrieved.LoadCountCreatorLeads(ctx, exec, mods...) + }, + ), CreatorNoteAudios: countThenLoadBuilder[Q]( "CreatorNoteAudios", func(ctx context.Context, exec bob.Executor, retrieved CreatorNoteAudiosCountInterface, mods ...bob.Mod[*dialect.SelectQuery]) error { @@ -4119,6 +4540,36 @@ func (os UserSlice) LoadCountCreatorComplianceReportRequests(ctx context.Context return nil } +// LoadCountCommitterFiles loads the count of CommitterFiles into the C struct +func (o *User) LoadCountCommitterFiles(ctx context.Context, exec bob.Executor, mods ...bob.Mod[*dialect.SelectQuery]) error { + if o == nil { + return nil + } + + count, err := o.CommitterFiles(mods...).Count(ctx, exec) + if err != nil { + return err + } + + o.C.CommitterFiles = &count + return nil +} + +// LoadCountCommitterFiles loads the count of CommitterFiles for a slice +func (os UserSlice) LoadCountCommitterFiles(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.LoadCountCommitterFiles(ctx, exec, mods...); err != nil { + return err + } + } + + return nil +} + // LoadCountCreatorFiles loads the count of CreatorFiles into the C struct func (o *User) LoadCountCreatorFiles(ctx context.Context, exec bob.Executor, mods ...bob.Mod[*dialect.SelectQuery]) error { if o == nil { @@ -4179,6 +4630,36 @@ func (os UserSlice) LoadCountFileuploadPool(ctx context.Context, exec bob.Execut return nil } +// LoadCountCreatorLeads loads the count of CreatorLeads into the C struct +func (o *User) LoadCountCreatorLeads(ctx context.Context, exec bob.Executor, mods ...bob.Mod[*dialect.SelectQuery]) error { + if o == nil { + return nil + } + + count, err := o.CreatorLeads(mods...).Count(ctx, exec) + if err != nil { + return err + } + + o.C.CreatorLeads = &count + return nil +} + +// LoadCountCreatorLeads loads the count of CreatorLeads for a slice +func (os UserSlice) LoadCountCreatorLeads(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.LoadCountCreatorLeads(ctx, exec, mods...); err != nil { + return err + } + } + + return nil +} + // LoadCountCreatorNoteAudios loads the count of CreatorNoteAudios into the C struct func (o *User) LoadCountCreatorNoteAudios(ctx context.Context, exec bob.Executor, mods ...bob.Mod[*dialect.SelectQuery]) error { if o == nil { @@ -4484,8 +4965,10 @@ type userJoins[Q dialect.Joinable] struct { UserOauthTokens modAs[Q, arcgisOauthTokenColumns] PublicUserUser modAs[Q, arcgisuserColumns] CreatorComplianceReportRequests modAs[Q, complianceReportRequestColumns] + CommitterFiles modAs[Q, fileuploadFileColumns] CreatorFiles modAs[Q, fileuploadFileColumns] FileuploadPool modAs[Q, fileuploadPoolColumns] + CreatorLeads modAs[Q, leadColumns] CreatorNoteAudios modAs[Q, noteAudioColumns] DeletorNoteAudios modAs[Q, noteAudioColumns] CreatorNoteImages modAs[Q, noteImageColumns] @@ -4548,6 +5031,20 @@ func buildUserJoins[Q dialect.Joinable](cols userColumns, typ string) userJoins[ return mods }, }, + CommitterFiles: modAs[Q, fileuploadFileColumns]{ + c: FileuploadFiles.Columns, + f: func(to fileuploadFileColumns) bob.Mod[Q] { + mods := make(mods.QueryMods[Q], 0, 1) + + { + mods = append(mods, dialect.Join[Q](typ, FileuploadFiles.Name().As(to.Alias())).On( + to.Committer.EQ(cols.ID), + )) + } + + return mods + }, + }, CreatorFiles: modAs[Q, fileuploadFileColumns]{ c: FileuploadFiles.Columns, f: func(to fileuploadFileColumns) bob.Mod[Q] { @@ -4576,6 +5073,20 @@ func buildUserJoins[Q dialect.Joinable](cols userColumns, typ string) userJoins[ return mods }, }, + CreatorLeads: modAs[Q, leadColumns]{ + c: Leads.Columns, + f: func(to leadColumns) bob.Mod[Q] { + mods := make(mods.QueryMods[Q], 0, 1) + + { + mods = append(mods, dialect.Join[Q](typ, Leads.Name().As(to.Alias())).On( + to.Creator.EQ(cols.ID), + )) + } + + return mods + }, + }, CreatorNoteAudios: modAs[Q, noteAudioColumns]{ c: NoteAudios.Columns, f: func(to noteAudioColumns) bob.Mod[Q] { diff --git a/platform/csv/csv.go b/platform/csv/csv.go index 6eebca15..530fd10b 100644 --- a/platform/csv/csv.go +++ b/platform/csv/csv.go @@ -8,10 +8,11 @@ import ( "strconv" "strings" //"sync" - //"time" + "time" "github.com/Gleipnir-Technology/bob" "github.com/Gleipnir-Technology/bob/dialect/psql" + "github.com/Gleipnir-Technology/bob/dialect/psql/im" "github.com/Gleipnir-Technology/bob/dialect/psql/um" //"github.com/Gleipnir-Technology/nidus-sync/config" "github.com/Gleipnir-Technology/nidus-sync/db" @@ -24,7 +25,7 @@ import ( //"github.com/Gleipnir-Technology/nidus-sync/stadia" //"github.com/Gleipnir-Technology/nidus-sync/userfile" "github.com/aarondl/opt/omit" - //"github.com/aarondl/opt/omitnull" + "github.com/aarondl/opt/omitnull" "github.com/rs/zerolog/log" ) @@ -37,13 +38,13 @@ func JobCommit(ctx context.Context, file_id int32) error { return fmt.Errorf("Failed to start transaction: %w", err) } - f, err := models.FindFileuploadFile(ctx, txn, file_id) + file, err := models.FindFileuploadFile(ctx, txn, file_id) if err != nil { return fmt.Errorf("Failed to get csv file %d from DB: %w", file_id, err) } - org, err := models.FindOrganization(ctx, txn, f.OrganizationID) + org, err := models.FindOrganization(ctx, txn, file.OrganizationID) if err != nil { - return fmt.Errorf("Failed to get org %d from DB: %w", f.OrganizationID, err) + return fmt.Errorf("Failed to get org %d from DB: %w", file.OrganizationID, err) } rows, err := models.FileuploadPools.Query( @@ -66,7 +67,84 @@ func JobCommit(ctx context.Context, file_id int32) error { if err != nil { return fmt.Errorf("ensure address: %w", err) } - log.Info().Int32("id", address.ID).Msg("made address") + parcel, err := geocode.GetParcel(ctx, txn, address) + if err != nil { + return fmt.Errorf("get parcel: %w", err) + } + var site *models.Site + site, err = models.Sites.Query( + models.SelectWhere.Sites.AddressID.EQ(address.ID), + ).One(ctx, txn) + if err != nil { + if err.Error() != "sql: no rows in result set" { + return fmt.Errorf("query site: %w", err) + } + setter := models.SiteSetter{ + AddressID: omit.From(address.ID), + Created: omit.From(time.Now()), + CreatorID: omit.FromPtr(file.Committer.Ptr()), + FileID: omitnull.From(file_id), + //ID omit.Val[int32] `db:"id,pk" ` + Notes: omit.From(row.Notes), + OrganizationID: omit.From(org.ID), + OwnerName: omit.From(row.PropertyOwnerName), + OwnerPhoneE164: omitnull.FromPtr(row.PropertyOwnerPhoneE164.Ptr()), + ParcelID: omit.From(parcel.ID), + ResidentOwned: omitnull.FromPtr(row.ResidentOwned.Ptr()), + Tags: omit.From(row.Tags), + Version: omit.From(int32(1)), + } + site, err = models.Sites.Insert(&setter).One(ctx, txn) + if err != nil { + return fmt.Errorf("insert site: %w", err) + } + } + var pool *models.Pool + pool, err = models.Pools.Query( + models.SelectWhere.Pools.SiteID.EQ(site.ID), + models.SelectWhere.Pools.SiteVersion.EQ(site.Version), + ).One(ctx, txn) + if err != nil { + if err.Error() != "sql: no rows in result set" { + return fmt.Errorf("query site: %w", err) + } + pool, err = models.Pools.Insert(&models.PoolSetter{ + Condition: omit.From(row.Condition), + Created: omit.From(time.Now()), + CreatorID: omit.From(file.Committer.MustGet()), + //ID: row.Address, + SiteID: omit.From(site.ID), + SiteVersion: omit.From(site.Version), + }).One(ctx, txn) + } + signal, err := models.Signals.Insert(&models.SignalSetter{ + Addressed: omitnull.FromPtr[time.Time](nil), + Addressor: omitnull.FromPtr[int32](nil), + Created: omit.From(time.Now()), + Creator: omit.From(file.Committer.MustGet()), + //ID: row.Address, + OrganizationID: omit.From(org.ID), + Species: omitnull.From(enums.MosquitospeciesNone), + Title: omit.From("Green pool import"), + Type: omit.From(enums.SignaltypeFlyoverPool), + }).One(ctx, txn) + if err != nil { + return fmt.Errorf("insert signal: %w", err) + } + _, err = bob.Exec(ctx, db.PGInstance.BobDB, psql.Insert( + im.Into("signa_pool", "pool_id", "signal_id"), + im.Values( + psql.Arg(pool.ID), + psql.Arg(signal.ID), + ), + )) + /* + Not sure why SignalPools doesn't have an Insert method + _, err = models.SignalPools.Insert(&models.SignalPoolSetter{ + PoolID: omit.From(pool.ID), + SignalID: omit.From(signal.ID), + }).One(ctx, txn) + */ } return nil } diff --git a/platform/csv/flyover.go b/platform/csv/flyover.go index 0c2c92c4..438ee70c 100644 --- a/platform/csv/flyover.go +++ b/platform/csv/flyover.go @@ -147,7 +147,7 @@ func insertFlyover(ctx context.Context, txn bob.Tx, file *models.FileuploadFile, //AddressRegion: omit.From(), //AddressStreet: omit.From(), Committed: omit.From(false), - Condition: omit.From(enums.FileuploadPoolconditiontypeUnknown), + Condition: omit.From(enums.PoolconditiontypeUnknown), Created: omit.From(time.Now()), CreatorID: omit.From(file.CreatorID), CSVFile: omit.From(file.ID), @@ -238,7 +238,7 @@ func insertPoollistRow(ctx context.Context, txn bob.Tx, file *models.FileuploadF // AddressPostalCode: omit.From(), // AddressStreet: omit.From(), Committed: omit.From(false), - Condition: omit.From(enums.FileuploadPoolconditiontypeUnknown), + Condition: omit.From(enums.PoolconditiontypeUnknown), Created: omit.From(time.Now()), CreatorID: omit.From(file.CreatorID), CSVFile: omit.From(file.ID), @@ -329,8 +329,8 @@ var poolConditionAliases = map[string]string{ "questionable": "unknown", } -func parsePoolCondition(c string) (enums.FileuploadPoolconditiontype, error) { - var condition enums.FileuploadPoolconditiontype +func parsePoolCondition(c string) (enums.Poolconditiontype, error) { + var condition enums.Poolconditiontype col_l := strings.ToLower(c) col_translated, ok := poolConditionAliases[col_l] if ok { diff --git a/platform/csv/pool.go b/platform/csv/pool.go index a833b12d..4975255a 100644 --- a/platform/csv/pool.go +++ b/platform/csv/pool.go @@ -193,7 +193,7 @@ func parseCSVPoollist(ctx context.Context, txn bob.Tx, file *models.FileuploadFi //AddressRegion: omit.From(), //AddressStreet: omit.From(), Committed: omit.From(false), - Condition: omit.From(enums.FileuploadPoolconditiontypeUnknown), + Condition: omit.From(enums.PoolconditiontypeUnknown), Created: omit.From(time.Now()), CreatorID: omit.From(file.CreatorID), CSVFile: omit.From(file.ID), @@ -231,7 +231,7 @@ func parseCSVPoollist(ctx context.Context, txn bob.Tx, file *models.FileuploadFi setter.AddressNumber = omit.From(parts[0]) setter.AddressStreet = omit.From(parts[1]) case headerPoolCondition: - var condition enums.FileuploadPoolconditiontype + var condition enums.Poolconditiontype col_l := strings.ToLower(col) col_translated := col_l switch col_l { @@ -241,7 +241,7 @@ func parseCSVPoollist(ctx context.Context, txn bob.Tx, file *models.FileuploadFi err := condition.Scan(col_translated) if err != nil { addError(ctx, txn, c, int32(line_number), int32(i), fmt.Sprintf("'%s' is not a pool condition that we recognize. It should be one of %s", col, poolConditionValidValues())) - setter.Condition = omit.From(enums.FileuploadPoolconditiontypeUnknown) + setter.Condition = omit.From(enums.PoolconditiontypeUnknown) continue } setter.Condition = omit.From(condition) @@ -356,7 +356,7 @@ func missingRequiredHeaders(headers []headerPoolEnum) []headerPoolEnum { } func poolConditionValidValues() string { var b strings.Builder - for i, cond := range enums.AllFileuploadPoolconditiontype() { + for i, cond := range enums.AllPoolconditiontype() { if i == 0 { fmt.Fprintf(&b, "'%s'", cond) } else { diff --git a/platform/geocode/geocode.go b/platform/geocode/geocode.go index 2b10e9c6..714d8512 100644 --- a/platform/geocode/geocode.go +++ b/platform/geocode/geocode.go @@ -9,6 +9,7 @@ import ( "github.com/Gleipnir-Technology/bob" "github.com/Gleipnir-Technology/bob/dialect/psql" "github.com/Gleipnir-Technology/bob/dialect/psql/im" + "github.com/Gleipnir-Technology/bob/dialect/psql/sm" "github.com/Gleipnir-Technology/nidus-sync/db/enums" "github.com/Gleipnir-Technology/nidus-sync/db/models" "github.com/Gleipnir-Technology/nidus-sync/h3utils" @@ -160,6 +161,16 @@ func Geocode(ctx context.Context, org *models.Organization, a Address) (GeocodeR }, nil } +func GetParcel(ctx context.Context, txn bob.Tx, a *models.Address) (*models.Parcel, error) { + result, err := models.Parcels.Query( + sm.InnerJoin("address").On(psql.F("ST_Contains", psql.Raw("parcel.geometry"), psql.Raw("address.geom"))), + models.SelectWhere.Addresses.ID.EQ(a.ID), + ).One(ctx, txn) + if err != nil { + return nil, fmt.Errorf("Get parcel from address %d: %w", a.ID) + } + return result, nil +} func maybeAddServiceArea(req *stadia.StructuredGeocodeRequest, org *models.Organization) { if org.ServiceAreaXmax.IsNull() || org.ServiceAreaYmax.IsNull() || diff --git a/platform/organization.go b/platform/organization.go index a04e9667..8782dd22 100644 --- a/platform/organization.go +++ b/platform/organization.go @@ -1,6 +1,17 @@ package platform +import ( + "github.com/Gleipnir-Technology/nidus-sync/db/models" +) + type Organization struct { - ID int + ID int32 Name string } + +func NewOrganization(org *models.Organization) Organization { + return Organization{ + ID: org.ID, + Name: org.Name, + } +} diff --git a/platform/upload.go b/platform/upload.go index f0d80f1e..38ba1f92 100644 --- a/platform/upload.go +++ b/platform/upload.go @@ -78,13 +78,14 @@ func NewUpload(ctx context.Context, u *models.User, upload userfile.FileUpload, ID: file.ID, }, nil } -func UploadCommit(ctx context.Context, org *models.Organization, file_id int32) error { +func UploadCommit(ctx context.Context, org *models.Organization, file_id int32, committer *models.User) error { // Create addresses for each row // Create sites for each row // Create pools for each row _, err := psql.Update( um.Table(models.FileuploadFiles.Alias()), um.SetCol("status").ToArg("committed"), + um.SetCol("committer").ToArg(committer.ID), um.Where(psql.Quote("id").EQ(psql.Arg(file_id))), um.Where(psql.Quote("organization_id").EQ(psql.Arg(org.ID))), ).Exec(ctx, db.PGInstance.BobDB) diff --git a/platform/user.go b/platform/user.go index 83c50609..8ba628b6 100644 --- a/platform/user.go +++ b/platform/user.go @@ -1,14 +1,39 @@ package platform import ( + "context" + "fmt" + + "github.com/Gleipnir-Technology/nidus-sync/db" + "github.com/Gleipnir-Technology/nidus-sync/db/models" "github.com/Gleipnir-Technology/nidus-sync/notification" ) type User struct { - DisplayName string + DisplayName string `json:"display_name"` Initials string Notifications []notification.Notification - Organization Organization - Role string - Username string + Organization Organization `json:"organization"` + Role string `json:"role"` + Username string `json:"username"` +} + +func UsersByID(ctx context.Context, org *models.Organization) (map[int32]*User, error) { + users, err := org.User().All(ctx, db.PGInstance.BobDB) + if err != nil { + return make(map[int32]*User, 0), fmt.Errorf("get all org users: %w", err) + } + organization := NewOrganization(org) + results := make(map[int32]*User, len(users)) + for _, user := range users { + results[user.ID] = &User{ + DisplayName: user.DisplayName, + Initials: "", + Notifications: []notification.Notification{}, + Organization: organization, + Role: user.Role.String(), + Username: user.Username, + } + } + return results, nil } diff --git a/sync/mailer.go b/sync/mailer.go index 41cc2707..ef65a3c8 100644 --- a/sync/mailer.go +++ b/sync/mailer.go @@ -55,7 +55,7 @@ func getMailerPreview(w http.ResponseWriter, r *http.Request) { ctx := r.Context() comp, err := models.ComplianceReportRequests.Query( - models.Preload.ComplianceReportRequest.Site(), + models.Preload.ComplianceReportRequest.Lead(), models.SelectWhere.ComplianceReportRequests.PublicID.EQ(code), ).One(ctx, db.PGInstance.BobDB) @@ -63,8 +63,8 @@ func getMailerPreview(w http.ResponseWriter, r *http.Request) { http.Error(w, "no comp", http.StatusInternalServerError) return } - site := comp.R.Site - org, err := models.FindOrganization(ctx, db.PGInstance.BobDB, site.OrganizationID) + lead := comp.R.Lead + org, err := models.FindOrganization(ctx, db.PGInstance.BobDB, lead.OrganizationID) if err != nil { http.Error(w, "no comp", http.StatusInternalServerError) return diff --git a/sync/upload.go b/sync/upload.go index 4872ab06..2137122e 100644 --- a/sync/upload.go +++ b/sync/upload.go @@ -83,7 +83,7 @@ func postUploadCommit(ctx context.Context, r *http.Request, org *models.Organiza if err != nil { return "", nhttp.NewError("Failed to parse file_id: %w", err) } - err = platform.UploadCommit(ctx, org, int32(file_id_)) + err = platform.UploadCommit(ctx, org, int32(file_id_), u) if err != nil { return "", nhttp.NewError("Failed to mark committed: %w", err) }