diff --git a/db/dberrors/publicreport.nuisance_image.bob.go b/db/dberrors/publicreport.nuisance_image.bob.go new file mode 100644 index 00000000..21d3cb63 --- /dev/null +++ b/db/dberrors/publicreport.nuisance_image.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 PublicreportNuisanceImageErrors = &publicreportNuisanceImageErrors{ + ErrUniqueNuisanceImagePkey: &UniqueConstraintError{ + schema: "publicreport", + table: "nuisance_image", + columns: []string{"image_id", "nuisance_id"}, + s: "nuisance_image_pkey", + }, +} + +type publicreportNuisanceImageErrors struct { + ErrUniqueNuisanceImagePkey *UniqueConstraintError +} diff --git a/db/dbinfo/publicreport.nuisance.bob.go b/db/dbinfo/publicreport.nuisance.bob.go index f41b5c99..6a25e937 100644 --- a/db/dbinfo/publicreport.nuisance.bob.go +++ b/db/dbinfo/publicreport.nuisance.bob.go @@ -168,6 +168,15 @@ var PublicreportNuisances = Table[ Generated: false, AutoIncr: false, }, + H3cell: column{ + Name: "h3cell", + DBType: "h3index", + Default: "NULL", + Comment: "", + Nullable: true, + Generated: false, + AutoIncr: false, + }, }, Indexes: publicreportNuisanceIndexes{ NuisancePkey: index{ @@ -250,11 +259,12 @@ type publicreportNuisanceColumns struct { Status column OrganizationID column SourceGutter column + H3cell column } func (c publicreportNuisanceColumns) AsSlice() []column { return []column{ - c.ID, c.AdditionalInfo, c.Created, c.Duration, c.SourceLocation, c.SourceContainer, c.SourceDescription, c.SourceStagnant, c.PublicID, c.ReporterEmail, c.ReporterName, c.ReporterPhone, c.Address, c.Location, c.Status, c.OrganizationID, c.SourceGutter, + c.ID, c.AdditionalInfo, c.Created, c.Duration, c.SourceLocation, c.SourceContainer, c.SourceDescription, c.SourceStagnant, c.PublicID, c.ReporterEmail, c.ReporterName, c.ReporterPhone, c.Address, c.Location, c.Status, c.OrganizationID, c.SourceGutter, c.H3cell, } } diff --git a/db/dbinfo/publicreport.nuisance_image.bob.go b/db/dbinfo/publicreport.nuisance_image.bob.go new file mode 100644 index 00000000..c038ed53 --- /dev/null +++ b/db/dbinfo/publicreport.nuisance_image.bob.go @@ -0,0 +1,132 @@ +// 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 PublicreportNuisanceImages = Table[ + publicreportNuisanceImageColumns, + publicreportNuisanceImageIndexes, + publicreportNuisanceImageForeignKeys, + publicreportNuisanceImageUniques, + publicreportNuisanceImageChecks, +]{ + Schema: "publicreport", + Name: "nuisance_image", + Columns: publicreportNuisanceImageColumns{ + ImageID: column{ + Name: "image_id", + DBType: "integer", + Default: "", + Comment: "", + Nullable: false, + Generated: false, + AutoIncr: false, + }, + NuisanceID: column{ + Name: "nuisance_id", + DBType: "integer", + Default: "", + Comment: "", + Nullable: false, + Generated: false, + AutoIncr: false, + }, + }, + Indexes: publicreportNuisanceImageIndexes{ + NuisanceImagePkey: index{ + Type: "btree", + Name: "nuisance_image_pkey", + Columns: []indexColumn{ + { + Name: "image_id", + Desc: null.FromCond(false, true), + IsExpression: false, + }, + { + Name: "nuisance_id", + Desc: null.FromCond(false, true), + IsExpression: false, + }, + }, + Unique: true, + Comment: "", + NullsFirst: []bool{false, false}, + NullsDistinct: false, + Where: "", + Include: []string{}, + }, + }, + PrimaryKey: &constraint{ + Name: "nuisance_image_pkey", + Columns: []string{"image_id", "nuisance_id"}, + Comment: "", + }, + ForeignKeys: publicreportNuisanceImageForeignKeys{ + PublicreportNuisanceImageNuisanceImageImageIDFkey: foreignKey{ + constraint: constraint{ + Name: "publicreport.nuisance_image.nuisance_image_image_id_fkey", + Columns: []string{"image_id"}, + Comment: "", + }, + ForeignTable: "publicreport.image", + ForeignColumns: []string{"id"}, + }, + PublicreportNuisanceImageNuisanceImageNuisanceIDFkey: foreignKey{ + constraint: constraint{ + Name: "publicreport.nuisance_image.nuisance_image_nuisance_id_fkey", + Columns: []string{"nuisance_id"}, + Comment: "", + }, + ForeignTable: "publicreport.nuisance", + ForeignColumns: []string{"id"}, + }, + }, + + Comment: "", +} + +type publicreportNuisanceImageColumns struct { + ImageID column + NuisanceID column +} + +func (c publicreportNuisanceImageColumns) AsSlice() []column { + return []column{ + c.ImageID, c.NuisanceID, + } +} + +type publicreportNuisanceImageIndexes struct { + NuisanceImagePkey index +} + +func (i publicreportNuisanceImageIndexes) AsSlice() []index { + return []index{ + i.NuisanceImagePkey, + } +} + +type publicreportNuisanceImageForeignKeys struct { + PublicreportNuisanceImageNuisanceImageImageIDFkey foreignKey + PublicreportNuisanceImageNuisanceImageNuisanceIDFkey foreignKey +} + +func (f publicreportNuisanceImageForeignKeys) AsSlice() []foreignKey { + return []foreignKey{ + f.PublicreportNuisanceImageNuisanceImageImageIDFkey, f.PublicreportNuisanceImageNuisanceImageNuisanceIDFkey, + } +} + +type publicreportNuisanceImageUniques struct{} + +func (u publicreportNuisanceImageUniques) AsSlice() []constraint { + return []constraint{} +} + +type publicreportNuisanceImageChecks struct{} + +func (c publicreportNuisanceImageChecks) AsSlice() []check { + return []check{} +} diff --git a/db/factory/bobfactory_context.bob.go b/db/factory/bobfactory_context.bob.go index 1ba4c471..dd9d0ef9 100644 --- a/db/factory/bobfactory_context.bob.go +++ b/db/factory/bobfactory_context.bob.go @@ -270,6 +270,7 @@ var ( // Relationship Contexts for publicreport.image publicreportImageWithParentsCascadingCtx = newContextual[bool]("publicreportImageWithParentsCascading") publicreportImageRelImageExifsCtx = newContextual[bool]("publicreport.image.publicreport.image_exif.publicreport.image_exif.image_exif_image_id_fkey") + publicreportImageRelNuisancesCtx = newContextual[bool]("publicreport.image.publicreport.nuisance.publicreport.nuisance_image.nuisance_image_image_id_fkeypublicreport.nuisance_image.nuisance_image_nuisance_id_fkey") publicreportImageRelPoolsCtx = newContextual[bool]("publicreport.image.publicreport.pool.publicreport.pool_image.pool_image_image_id_fkeypublicreport.pool_image.pool_image_pool_id_fkey") publicreportImageRelQuicksCtx = newContextual[bool]("publicreport.image.publicreport.quick.publicreport.quick_image.quick_image_image_id_fkeypublicreport.quick_image.quick_image_quick_id_fkey") @@ -280,6 +281,12 @@ var ( // Relationship Contexts for publicreport.nuisance publicreportNuisanceWithParentsCascadingCtx = newContextual[bool]("publicreportNuisanceWithParentsCascading") publicreportNuisanceRelOrganizationCtx = newContextual[bool]("organization.publicreport.nuisance.publicreport.nuisance.nuisance_organization_id_fkey") + publicreportNuisanceRelImagesCtx = newContextual[bool]("publicreport.image.publicreport.nuisance.publicreport.nuisance_image.nuisance_image_image_id_fkeypublicreport.nuisance_image.nuisance_image_nuisance_id_fkey") + + // Relationship Contexts for publicreport.nuisance_image + publicreportNuisanceImageWithParentsCascadingCtx = newContextual[bool]("publicreportNuisanceImageWithParentsCascading") + publicreportNuisanceImageRelImageCtx = newContextual[bool]("publicreport.image.publicreport.nuisance_image.publicreport.nuisance_image.nuisance_image_image_id_fkey") + publicreportNuisanceImageRelNuisanceCtx = newContextual[bool]("publicreport.nuisance.publicreport.nuisance_image.publicreport.nuisance_image.nuisance_image_nuisance_id_fkey") // Relationship Contexts for publicreport.pool publicreportPoolWithParentsCascadingCtx = newContextual[bool]("publicreportPoolWithParentsCascading") diff --git a/db/factory/bobfactory_main.bob.go b/db/factory/bobfactory_main.bob.go index f7d7773f..99482d95 100644 --- a/db/factory/bobfactory_main.bob.go +++ b/db/factory/bobfactory_main.bob.go @@ -74,6 +74,7 @@ type Factory struct { basePublicreportImageMods PublicreportImageModSlice basePublicreportImageExifMods PublicreportImageExifModSlice basePublicreportNuisanceMods PublicreportNuisanceModSlice + basePublicreportNuisanceImageMods PublicreportNuisanceImageModSlice basePublicreportPoolMods PublicreportPoolModSlice basePublicreportPoolImageMods PublicreportPoolImageModSlice basePublicreportQuickMods PublicreportQuickModSlice @@ -2867,6 +2868,9 @@ func (f *Factory) FromExistingPublicreportImage(m *models.PublicreportImage) *Pu if len(m.R.ImageExifs) > 0 { PublicreportImageMods.AddExistingImageExifs(m.R.ImageExifs...).Apply(ctx, o) } + if len(m.R.Nuisances) > 0 { + PublicreportImageMods.AddExistingNuisances(m.R.Nuisances...).Apply(ctx, o) + } if len(m.R.Pools) > 0 { PublicreportImageMods.AddExistingPools(m.R.Pools...).Apply(ctx, o) } @@ -2944,11 +2948,48 @@ func (f *Factory) FromExistingPublicreportNuisance(m *models.PublicreportNuisanc o.Status = func() enums.PublicreportReportstatustype { return m.Status } o.OrganizationID = func() null.Val[int32] { return m.OrganizationID } o.SourceGutter = func() bool { return m.SourceGutter } + o.H3cell = func() null.Val[string] { return m.H3cell } ctx := context.Background() if m.R.Organization != nil { PublicreportNuisanceMods.WithExistingOrganization(m.R.Organization).Apply(ctx, o) } + if len(m.R.Images) > 0 { + PublicreportNuisanceMods.AddExistingImages(m.R.Images...).Apply(ctx, o) + } + + return o +} + +func (f *Factory) NewPublicreportNuisanceImage(mods ...PublicreportNuisanceImageMod) *PublicreportNuisanceImageTemplate { + return f.NewPublicreportNuisanceImageWithContext(context.Background(), mods...) +} + +func (f *Factory) NewPublicreportNuisanceImageWithContext(ctx context.Context, mods ...PublicreportNuisanceImageMod) *PublicreportNuisanceImageTemplate { + o := &PublicreportNuisanceImageTemplate{f: f} + + if f != nil { + f.basePublicreportNuisanceImageMods.Apply(ctx, o) + } + + PublicreportNuisanceImageModSlice(mods).Apply(ctx, o) + + return o +} + +func (f *Factory) FromExistingPublicreportNuisanceImage(m *models.PublicreportNuisanceImage) *PublicreportNuisanceImageTemplate { + o := &PublicreportNuisanceImageTemplate{f: f, alreadyPersisted: true} + + o.ImageID = func() int32 { return m.ImageID } + o.NuisanceID = func() int32 { return m.NuisanceID } + + ctx := context.Background() + if m.R.Image != nil { + PublicreportNuisanceImageMods.WithExistingImage(m.R.Image).Apply(ctx, o) + } + if m.R.Nuisance != nil { + PublicreportNuisanceImageMods.WithExistingNuisance(m.R.Nuisance).Apply(ctx, o) + } return o } @@ -3780,6 +3821,14 @@ func (f *Factory) AddBasePublicreportNuisanceMod(mods ...PublicreportNuisanceMod f.basePublicreportNuisanceMods = append(f.basePublicreportNuisanceMods, mods...) } +func (f *Factory) ClearBasePublicreportNuisanceImageMods() { + f.basePublicreportNuisanceImageMods = nil +} + +func (f *Factory) AddBasePublicreportNuisanceImageMod(mods ...PublicreportNuisanceImageMod) { + f.basePublicreportNuisanceImageMods = append(f.basePublicreportNuisanceImageMods, mods...) +} + func (f *Factory) ClearBasePublicreportPoolMods() { f.basePublicreportPoolMods = nil } diff --git a/db/factory/publicreport.image.bob.go b/db/factory/publicreport.image.bob.go index 7772d7a9..beaf1b5f 100644 --- a/db/factory/publicreport.image.bob.go +++ b/db/factory/publicreport.image.bob.go @@ -56,6 +56,7 @@ type PublicreportImageTemplate struct { type publicreportImageR struct { ImageExifs []*publicreportImageRImageExifsR + Nuisances []*publicreportImageRNuisancesR Pools []*publicreportImageRPoolsR Quicks []*publicreportImageRQuicksR } @@ -64,6 +65,10 @@ type publicreportImageRImageExifsR struct { number int o *PublicreportImageExifTemplate } +type publicreportImageRNuisancesR struct { + number int + o *PublicreportNuisanceTemplate +} type publicreportImageRPoolsR struct { number int o *PublicreportPoolTemplate @@ -96,6 +101,18 @@ func (t PublicreportImageTemplate) setModelRels(o *models.PublicreportImage) { o.R.ImageExifs = rel } + if t.r.Nuisances != nil { + rel := models.PublicreportNuisanceSlice{} + for _, r := range t.r.Nuisances { + related := r.o.BuildMany(r.number) + for _, rel := range related { + rel.R.Images = append(rel.R.Images, o) + } + rel = append(rel, related...) + } + o.R.Nuisances = rel + } + if t.r.Pools != nil { rel := models.PublicreportPoolSlice{} for _, r := range t.r.Pools { @@ -287,6 +304,26 @@ func (o *PublicreportImageTemplate) insertOptRels(ctx context.Context, exec bob. } } + isNuisancesDone, _ := publicreportImageRelNuisancesCtx.Value(ctx) + if !isNuisancesDone && o.r.Nuisances != nil { + ctx = publicreportImageRelNuisancesCtx.WithValue(ctx, true) + for _, r := range o.r.Nuisances { + if r.o.alreadyPersisted { + m.R.Nuisances = append(m.R.Nuisances, r.o.Build()) + } else { + rel1, err := r.o.CreateMany(ctx, exec, r.number) + if err != nil { + return err + } + + err = m.AttachNuisances(ctx, exec, rel1...) + if err != nil { + return err + } + } + } + } + isPoolsDone, _ := publicreportImageRelPoolsCtx.Value(ctx) if !isPoolsDone && o.r.Pools != nil { ctx = publicreportImageRelPoolsCtx.WithValue(ctx, true) @@ -294,12 +331,12 @@ func (o *PublicreportImageTemplate) insertOptRels(ctx context.Context, exec bob. if r.o.alreadyPersisted { m.R.Pools = append(m.R.Pools, r.o.Build()) } else { - rel1, err := r.o.CreateMany(ctx, exec, r.number) + rel2, err := r.o.CreateMany(ctx, exec, r.number) if err != nil { return err } - err = m.AttachPools(ctx, exec, rel1...) + err = m.AttachPools(ctx, exec, rel2...) if err != nil { return err } @@ -314,12 +351,12 @@ func (o *PublicreportImageTemplate) insertOptRels(ctx context.Context, exec bob. if r.o.alreadyPersisted { m.R.Quicks = append(m.R.Quicks, r.o.Build()) } else { - rel2, err := r.o.CreateMany(ctx, exec, r.number) + rel3, err := r.o.CreateMany(ctx, exec, r.number) if err != nil { return err } - err = m.AttachQuicks(ctx, exec, rel2...) + err = m.AttachQuicks(ctx, exec, rel3...) if err != nil { return err } @@ -789,6 +826,54 @@ func (m publicreportImageMods) WithoutImageExifs() PublicreportImageMod { }) } +func (m publicreportImageMods) WithNuisances(number int, related *PublicreportNuisanceTemplate) PublicreportImageMod { + return PublicreportImageModFunc(func(ctx context.Context, o *PublicreportImageTemplate) { + o.r.Nuisances = []*publicreportImageRNuisancesR{{ + number: number, + o: related, + }} + }) +} + +func (m publicreportImageMods) WithNewNuisances(number int, mods ...PublicreportNuisanceMod) PublicreportImageMod { + return PublicreportImageModFunc(func(ctx context.Context, o *PublicreportImageTemplate) { + related := o.f.NewPublicreportNuisanceWithContext(ctx, mods...) + m.WithNuisances(number, related).Apply(ctx, o) + }) +} + +func (m publicreportImageMods) AddNuisances(number int, related *PublicreportNuisanceTemplate) PublicreportImageMod { + return PublicreportImageModFunc(func(ctx context.Context, o *PublicreportImageTemplate) { + o.r.Nuisances = append(o.r.Nuisances, &publicreportImageRNuisancesR{ + number: number, + o: related, + }) + }) +} + +func (m publicreportImageMods) AddNewNuisances(number int, mods ...PublicreportNuisanceMod) PublicreportImageMod { + return PublicreportImageModFunc(func(ctx context.Context, o *PublicreportImageTemplate) { + related := o.f.NewPublicreportNuisanceWithContext(ctx, mods...) + m.AddNuisances(number, related).Apply(ctx, o) + }) +} + +func (m publicreportImageMods) AddExistingNuisances(existingModels ...*models.PublicreportNuisance) PublicreportImageMod { + return PublicreportImageModFunc(func(ctx context.Context, o *PublicreportImageTemplate) { + for _, em := range existingModels { + o.r.Nuisances = append(o.r.Nuisances, &publicreportImageRNuisancesR{ + o: o.f.FromExistingPublicreportNuisance(em), + }) + } + }) +} + +func (m publicreportImageMods) WithoutNuisances() PublicreportImageMod { + return PublicreportImageModFunc(func(ctx context.Context, o *PublicreportImageTemplate) { + o.r.Nuisances = nil + }) +} + func (m publicreportImageMods) WithPools(number int, related *PublicreportPoolTemplate) PublicreportImageMod { return PublicreportImageModFunc(func(ctx context.Context, o *PublicreportImageTemplate) { o.r.Pools = []*publicreportImageRPoolsR{{ diff --git a/db/factory/publicreport.nuisance.bob.go b/db/factory/publicreport.nuisance.bob.go index 54ba0be6..a753063a 100644 --- a/db/factory/publicreport.nuisance.bob.go +++ b/db/factory/publicreport.nuisance.bob.go @@ -55,6 +55,7 @@ type PublicreportNuisanceTemplate struct { Status func() enums.PublicreportReportstatustype OrganizationID func() null.Val[int32] SourceGutter func() bool + H3cell func() null.Val[string] r publicreportNuisanceR f *Factory @@ -64,11 +65,16 @@ type PublicreportNuisanceTemplate struct { type publicreportNuisanceR struct { Organization *publicreportNuisanceROrganizationR + Images []*publicreportNuisanceRImagesR } type publicreportNuisanceROrganizationR struct { o *OrganizationTemplate } +type publicreportNuisanceRImagesR struct { + number int + o *PublicreportImageTemplate +} // Apply mods to the PublicreportNuisanceTemplate func (o *PublicreportNuisanceTemplate) Apply(ctx context.Context, mods ...PublicreportNuisanceMod) { @@ -86,6 +92,18 @@ func (t PublicreportNuisanceTemplate) setModelRels(o *models.PublicreportNuisanc o.OrganizationID = null.From(rel.ID) // h2 o.R.Organization = rel } + + if t.r.Images != nil { + rel := models.PublicreportImageSlice{} + for _, r := range t.r.Images { + related := r.o.BuildMany(r.number) + for _, rel := range related { + rel.R.Nuisances = append(rel.R.Nuisances, o) + } + rel = append(rel, related...) + } + o.R.Images = rel + } } // BuildSetter returns an *models.PublicreportNuisanceSetter @@ -161,6 +179,10 @@ func (o PublicreportNuisanceTemplate) BuildSetter() *models.PublicreportNuisance val := o.SourceGutter() m.SourceGutter = omit.From(val) } + if o.H3cell != nil { + val := o.H3cell() + m.H3cell = omitnull.FromNull(val) + } return m } @@ -234,6 +256,9 @@ func (o PublicreportNuisanceTemplate) Build() *models.PublicreportNuisance { if o.SourceGutter != nil { m.SourceGutter = o.SourceGutter() } + if o.H3cell != nil { + m.H3cell = o.H3cell() + } o.setModelRels(m) @@ -325,6 +350,26 @@ func (o *PublicreportNuisanceTemplate) insertOptRels(ctx context.Context, exec b } + isImagesDone, _ := publicreportNuisanceRelImagesCtx.Value(ctx) + if !isImagesDone && o.r.Images != nil { + ctx = publicreportNuisanceRelImagesCtx.WithValue(ctx, true) + for _, r := range o.r.Images { + if r.o.alreadyPersisted { + m.R.Images = append(m.R.Images, r.o.Build()) + } else { + rel1, err := r.o.CreateMany(ctx, exec, r.number) + if err != nil { + return err + } + + err = m.AttachImages(ctx, exec, rel1...) + if err != nil { + return err + } + } + } + } + return err } @@ -434,6 +479,7 @@ func (m publicreportNuisanceMods) RandomizeAllColumns(f *faker.Faker) Publicrepo PublicreportNuisanceMods.RandomStatus(f), PublicreportNuisanceMods.RandomOrganizationID(f), PublicreportNuisanceMods.RandomSourceGutter(f), + PublicreportNuisanceMods.RandomH3cell(f), } } @@ -1074,6 +1120,59 @@ func (m publicreportNuisanceMods) RandomSourceGutter(f *faker.Faker) Publicrepor }) } +// Set the model columns to this value +func (m publicreportNuisanceMods) H3cell(val null.Val[string]) PublicreportNuisanceMod { + return PublicreportNuisanceModFunc(func(_ context.Context, o *PublicreportNuisanceTemplate) { + o.H3cell = func() null.Val[string] { return val } + }) +} + +// Set the Column from the function +func (m publicreportNuisanceMods) H3cellFunc(f func() null.Val[string]) PublicreportNuisanceMod { + return PublicreportNuisanceModFunc(func(_ context.Context, o *PublicreportNuisanceTemplate) { + o.H3cell = f + }) +} + +// Clear any values for the column +func (m publicreportNuisanceMods) UnsetH3cell() PublicreportNuisanceMod { + return PublicreportNuisanceModFunc(func(_ context.Context, o *PublicreportNuisanceTemplate) { + o.H3cell = 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 publicreportNuisanceMods) RandomH3cell(f *faker.Faker) PublicreportNuisanceMod { + return PublicreportNuisanceModFunc(func(_ context.Context, o *PublicreportNuisanceTemplate) { + o.H3cell = func() null.Val[string] { + if f == nil { + f = &defaultFaker + } + + val := random_string(f) + return null.From(val) + } + }) +} + +// Generates a random value for the column using the given faker +// if faker is nil, a default faker is used +// The generated value is never null +func (m publicreportNuisanceMods) RandomH3cellNotNull(f *faker.Faker) PublicreportNuisanceMod { + return PublicreportNuisanceModFunc(func(_ context.Context, o *PublicreportNuisanceTemplate) { + o.H3cell = func() null.Val[string] { + if f == nil { + f = &defaultFaker + } + + val := random_string(f) + return null.From(val) + } + }) +} + func (m publicreportNuisanceMods) WithParentsCascading() PublicreportNuisanceMod { return PublicreportNuisanceModFunc(func(ctx context.Context, o *PublicreportNuisanceTemplate) { if isDone, _ := publicreportNuisanceWithParentsCascadingCtx.Value(ctx); isDone { @@ -1117,3 +1216,51 @@ func (m publicreportNuisanceMods) WithoutOrganization() PublicreportNuisanceMod o.r.Organization = nil }) } + +func (m publicreportNuisanceMods) WithImages(number int, related *PublicreportImageTemplate) PublicreportNuisanceMod { + return PublicreportNuisanceModFunc(func(ctx context.Context, o *PublicreportNuisanceTemplate) { + o.r.Images = []*publicreportNuisanceRImagesR{{ + number: number, + o: related, + }} + }) +} + +func (m publicreportNuisanceMods) WithNewImages(number int, mods ...PublicreportImageMod) PublicreportNuisanceMod { + return PublicreportNuisanceModFunc(func(ctx context.Context, o *PublicreportNuisanceTemplate) { + related := o.f.NewPublicreportImageWithContext(ctx, mods...) + m.WithImages(number, related).Apply(ctx, o) + }) +} + +func (m publicreportNuisanceMods) AddImages(number int, related *PublicreportImageTemplate) PublicreportNuisanceMod { + return PublicreportNuisanceModFunc(func(ctx context.Context, o *PublicreportNuisanceTemplate) { + o.r.Images = append(o.r.Images, &publicreportNuisanceRImagesR{ + number: number, + o: related, + }) + }) +} + +func (m publicreportNuisanceMods) AddNewImages(number int, mods ...PublicreportImageMod) PublicreportNuisanceMod { + return PublicreportNuisanceModFunc(func(ctx context.Context, o *PublicreportNuisanceTemplate) { + related := o.f.NewPublicreportImageWithContext(ctx, mods...) + m.AddImages(number, related).Apply(ctx, o) + }) +} + +func (m publicreportNuisanceMods) AddExistingImages(existingModels ...*models.PublicreportImage) PublicreportNuisanceMod { + return PublicreportNuisanceModFunc(func(ctx context.Context, o *PublicreportNuisanceTemplate) { + for _, em := range existingModels { + o.r.Images = append(o.r.Images, &publicreportNuisanceRImagesR{ + o: o.f.FromExistingPublicreportImage(em), + }) + } + }) +} + +func (m publicreportNuisanceMods) WithoutImages() PublicreportNuisanceMod { + return PublicreportNuisanceModFunc(func(ctx context.Context, o *PublicreportNuisanceTemplate) { + o.r.Images = nil + }) +} diff --git a/db/factory/publicreport.nuisance_image.bob.go b/db/factory/publicreport.nuisance_image.bob.go new file mode 100644 index 00000000..0ad1d6e5 --- /dev/null +++ b/db/factory/publicreport.nuisance_image.bob.go @@ -0,0 +1,431 @@ +// 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" + + "github.com/Gleipnir-Technology/bob" + models "github.com/Gleipnir-Technology/nidus-sync/db/models" + "github.com/aarondl/opt/omit" + "github.com/jaswdr/faker/v2" +) + +type PublicreportNuisanceImageMod interface { + Apply(context.Context, *PublicreportNuisanceImageTemplate) +} + +type PublicreportNuisanceImageModFunc func(context.Context, *PublicreportNuisanceImageTemplate) + +func (f PublicreportNuisanceImageModFunc) Apply(ctx context.Context, n *PublicreportNuisanceImageTemplate) { + f(ctx, n) +} + +type PublicreportNuisanceImageModSlice []PublicreportNuisanceImageMod + +func (mods PublicreportNuisanceImageModSlice) Apply(ctx context.Context, n *PublicreportNuisanceImageTemplate) { + for _, f := range mods { + f.Apply(ctx, n) + } +} + +// PublicreportNuisanceImageTemplate is an object representing the database table. +// all columns are optional and should be set by mods +type PublicreportNuisanceImageTemplate struct { + ImageID func() int32 + NuisanceID func() int32 + + r publicreportNuisanceImageR + f *Factory + + alreadyPersisted bool +} + +type publicreportNuisanceImageR struct { + Image *publicreportNuisanceImageRImageR + Nuisance *publicreportNuisanceImageRNuisanceR +} + +type publicreportNuisanceImageRImageR struct { + o *PublicreportImageTemplate +} +type publicreportNuisanceImageRNuisanceR struct { + o *PublicreportNuisanceTemplate +} + +// Apply mods to the PublicreportNuisanceImageTemplate +func (o *PublicreportNuisanceImageTemplate) Apply(ctx context.Context, mods ...PublicreportNuisanceImageMod) { + for _, mod := range mods { + mod.Apply(ctx, o) + } +} + +// setModelRels creates and sets the relationships on *models.PublicreportNuisanceImage +// according to the relationships in the template. Nothing is inserted into the db +func (t PublicreportNuisanceImageTemplate) setModelRels(o *models.PublicreportNuisanceImage) { + if t.r.Image != nil { + rel := t.r.Image.o.Build() + o.ImageID = rel.ID // h2 + o.R.Image = rel + } + + if t.r.Nuisance != nil { + rel := t.r.Nuisance.o.Build() + o.NuisanceID = rel.ID // h2 + o.R.Nuisance = rel + } +} + +// BuildSetter returns an *models.PublicreportNuisanceImageSetter +// this does nothing with the relationship templates +func (o PublicreportNuisanceImageTemplate) BuildSetter() *models.PublicreportNuisanceImageSetter { + m := &models.PublicreportNuisanceImageSetter{} + + if o.ImageID != nil { + val := o.ImageID() + m.ImageID = omit.From(val) + } + if o.NuisanceID != nil { + val := o.NuisanceID() + m.NuisanceID = omit.From(val) + } + + return m +} + +// BuildManySetter returns an []*models.PublicreportNuisanceImageSetter +// this does nothing with the relationship templates +func (o PublicreportNuisanceImageTemplate) BuildManySetter(number int) []*models.PublicreportNuisanceImageSetter { + m := make([]*models.PublicreportNuisanceImageSetter, number) + + for i := range m { + m[i] = o.BuildSetter() + } + + return m +} + +// Build returns an *models.PublicreportNuisanceImage +// Related objects are also created and placed in the .R field +// NOTE: Objects are not inserted into the database. Use PublicreportNuisanceImageTemplate.Create +func (o PublicreportNuisanceImageTemplate) Build() *models.PublicreportNuisanceImage { + m := &models.PublicreportNuisanceImage{} + + if o.ImageID != nil { + m.ImageID = o.ImageID() + } + if o.NuisanceID != nil { + m.NuisanceID = o.NuisanceID() + } + + o.setModelRels(m) + + return m +} + +// BuildMany returns an models.PublicreportNuisanceImageSlice +// Related objects are also created and placed in the .R field +// NOTE: Objects are not inserted into the database. Use PublicreportNuisanceImageTemplate.CreateMany +func (o PublicreportNuisanceImageTemplate) BuildMany(number int) models.PublicreportNuisanceImageSlice { + m := make(models.PublicreportNuisanceImageSlice, number) + + for i := range m { + m[i] = o.Build() + } + + return m +} + +func ensureCreatablePublicreportNuisanceImage(m *models.PublicreportNuisanceImageSetter) { + if !(m.ImageID.IsValue()) { + val := random_int32(nil) + m.ImageID = omit.From(val) + } + if !(m.NuisanceID.IsValue()) { + val := random_int32(nil) + m.NuisanceID = omit.From(val) + } +} + +// insertOptRels creates and inserts any optional the relationships on *models.PublicreportNuisanceImage +// according to the relationships in the template. +// any required relationship should have already exist on the model +func (o *PublicreportNuisanceImageTemplate) insertOptRels(ctx context.Context, exec bob.Executor, m *models.PublicreportNuisanceImage) error { + var err error + + return err +} + +// Create builds a publicreportNuisanceImage and inserts it into the database +// Relations objects are also inserted and placed in the .R field +func (o *PublicreportNuisanceImageTemplate) Create(ctx context.Context, exec bob.Executor) (*models.PublicreportNuisanceImage, error) { + var err error + opt := o.BuildSetter() + ensureCreatablePublicreportNuisanceImage(opt) + + if o.r.Image == nil { + PublicreportNuisanceImageMods.WithNewImage().Apply(ctx, o) + } + + var rel0 *models.PublicreportImage + + if o.r.Image.o.alreadyPersisted { + rel0 = o.r.Image.o.Build() + } else { + rel0, err = o.r.Image.o.Create(ctx, exec) + if err != nil { + return nil, err + } + } + + opt.ImageID = omit.From(rel0.ID) + + if o.r.Nuisance == nil { + PublicreportNuisanceImageMods.WithNewNuisance().Apply(ctx, o) + } + + var rel1 *models.PublicreportNuisance + + if o.r.Nuisance.o.alreadyPersisted { + rel1 = o.r.Nuisance.o.Build() + } else { + rel1, err = o.r.Nuisance.o.Create(ctx, exec) + if err != nil { + return nil, err + } + } + + opt.NuisanceID = omit.From(rel1.ID) + + m, err := models.PublicreportNuisanceImages.Insert(opt).One(ctx, exec) + if err != nil { + return nil, err + } + + m.R.Image = rel0 + m.R.Nuisance = rel1 + + if err := o.insertOptRels(ctx, exec, m); err != nil { + return nil, err + } + return m, err +} + +// MustCreate builds a publicreportNuisanceImage and inserts it into the database +// Relations objects are also inserted and placed in the .R field +// panics if an error occurs +func (o *PublicreportNuisanceImageTemplate) MustCreate(ctx context.Context, exec bob.Executor) *models.PublicreportNuisanceImage { + m, err := o.Create(ctx, exec) + if err != nil { + panic(err) + } + return m +} + +// CreateOrFail builds a publicreportNuisanceImage 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 *PublicreportNuisanceImageTemplate) CreateOrFail(ctx context.Context, tb testing.TB, exec bob.Executor) *models.PublicreportNuisanceImage { + tb.Helper() + m, err := o.Create(ctx, exec) + if err != nil { + tb.Fatal(err) + return nil + } + return m +} + +// CreateMany builds multiple publicreportNuisanceImages and inserts them into the database +// Relations objects are also inserted and placed in the .R field +func (o PublicreportNuisanceImageTemplate) CreateMany(ctx context.Context, exec bob.Executor, number int) (models.PublicreportNuisanceImageSlice, error) { + var err error + m := make(models.PublicreportNuisanceImageSlice, number) + + for i := range m { + m[i], err = o.Create(ctx, exec) + if err != nil { + return nil, err + } + } + + return m, nil +} + +// MustCreateMany builds multiple publicreportNuisanceImages and inserts them into the database +// Relations objects are also inserted and placed in the .R field +// panics if an error occurs +func (o PublicreportNuisanceImageTemplate) MustCreateMany(ctx context.Context, exec bob.Executor, number int) models.PublicreportNuisanceImageSlice { + m, err := o.CreateMany(ctx, exec, number) + if err != nil { + panic(err) + } + return m +} + +// CreateManyOrFail builds multiple publicreportNuisanceImages 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 PublicreportNuisanceImageTemplate) CreateManyOrFail(ctx context.Context, tb testing.TB, exec bob.Executor, number int) models.PublicreportNuisanceImageSlice { + tb.Helper() + m, err := o.CreateMany(ctx, exec, number) + if err != nil { + tb.Fatal(err) + return nil + } + return m +} + +// PublicreportNuisanceImage has methods that act as mods for the PublicreportNuisanceImageTemplate +var PublicreportNuisanceImageMods publicreportNuisanceImageMods + +type publicreportNuisanceImageMods struct{} + +func (m publicreportNuisanceImageMods) RandomizeAllColumns(f *faker.Faker) PublicreportNuisanceImageMod { + return PublicreportNuisanceImageModSlice{ + PublicreportNuisanceImageMods.RandomImageID(f), + PublicreportNuisanceImageMods.RandomNuisanceID(f), + } +} + +// Set the model columns to this value +func (m publicreportNuisanceImageMods) ImageID(val int32) PublicreportNuisanceImageMod { + return PublicreportNuisanceImageModFunc(func(_ context.Context, o *PublicreportNuisanceImageTemplate) { + o.ImageID = func() int32 { return val } + }) +} + +// Set the Column from the function +func (m publicreportNuisanceImageMods) ImageIDFunc(f func() int32) PublicreportNuisanceImageMod { + return PublicreportNuisanceImageModFunc(func(_ context.Context, o *PublicreportNuisanceImageTemplate) { + o.ImageID = f + }) +} + +// Clear any values for the column +func (m publicreportNuisanceImageMods) UnsetImageID() PublicreportNuisanceImageMod { + return PublicreportNuisanceImageModFunc(func(_ context.Context, o *PublicreportNuisanceImageTemplate) { + o.ImageID = nil + }) +} + +// Generates a random value for the column using the given faker +// if faker is nil, a default faker is used +func (m publicreportNuisanceImageMods) RandomImageID(f *faker.Faker) PublicreportNuisanceImageMod { + return PublicreportNuisanceImageModFunc(func(_ context.Context, o *PublicreportNuisanceImageTemplate) { + o.ImageID = func() int32 { + return random_int32(f) + } + }) +} + +// Set the model columns to this value +func (m publicreportNuisanceImageMods) NuisanceID(val int32) PublicreportNuisanceImageMod { + return PublicreportNuisanceImageModFunc(func(_ context.Context, o *PublicreportNuisanceImageTemplate) { + o.NuisanceID = func() int32 { return val } + }) +} + +// Set the Column from the function +func (m publicreportNuisanceImageMods) NuisanceIDFunc(f func() int32) PublicreportNuisanceImageMod { + return PublicreportNuisanceImageModFunc(func(_ context.Context, o *PublicreportNuisanceImageTemplate) { + o.NuisanceID = f + }) +} + +// Clear any values for the column +func (m publicreportNuisanceImageMods) UnsetNuisanceID() PublicreportNuisanceImageMod { + return PublicreportNuisanceImageModFunc(func(_ context.Context, o *PublicreportNuisanceImageTemplate) { + o.NuisanceID = nil + }) +} + +// Generates a random value for the column using the given faker +// if faker is nil, a default faker is used +func (m publicreportNuisanceImageMods) RandomNuisanceID(f *faker.Faker) PublicreportNuisanceImageMod { + return PublicreportNuisanceImageModFunc(func(_ context.Context, o *PublicreportNuisanceImageTemplate) { + o.NuisanceID = func() int32 { + return random_int32(f) + } + }) +} + +func (m publicreportNuisanceImageMods) WithParentsCascading() PublicreportNuisanceImageMod { + return PublicreportNuisanceImageModFunc(func(ctx context.Context, o *PublicreportNuisanceImageTemplate) { + if isDone, _ := publicreportNuisanceImageWithParentsCascadingCtx.Value(ctx); isDone { + return + } + ctx = publicreportNuisanceImageWithParentsCascadingCtx.WithValue(ctx, true) + { + + related := o.f.NewPublicreportImageWithContext(ctx, PublicreportImageMods.WithParentsCascading()) + m.WithImage(related).Apply(ctx, o) + } + { + + related := o.f.NewPublicreportNuisanceWithContext(ctx, PublicreportNuisanceMods.WithParentsCascading()) + m.WithNuisance(related).Apply(ctx, o) + } + }) +} + +func (m publicreportNuisanceImageMods) WithImage(rel *PublicreportImageTemplate) PublicreportNuisanceImageMod { + return PublicreportNuisanceImageModFunc(func(ctx context.Context, o *PublicreportNuisanceImageTemplate) { + o.r.Image = &publicreportNuisanceImageRImageR{ + o: rel, + } + }) +} + +func (m publicreportNuisanceImageMods) WithNewImage(mods ...PublicreportImageMod) PublicreportNuisanceImageMod { + return PublicreportNuisanceImageModFunc(func(ctx context.Context, o *PublicreportNuisanceImageTemplate) { + related := o.f.NewPublicreportImageWithContext(ctx, mods...) + + m.WithImage(related).Apply(ctx, o) + }) +} + +func (m publicreportNuisanceImageMods) WithExistingImage(em *models.PublicreportImage) PublicreportNuisanceImageMod { + return PublicreportNuisanceImageModFunc(func(ctx context.Context, o *PublicreportNuisanceImageTemplate) { + o.r.Image = &publicreportNuisanceImageRImageR{ + o: o.f.FromExistingPublicreportImage(em), + } + }) +} + +func (m publicreportNuisanceImageMods) WithoutImage() PublicreportNuisanceImageMod { + return PublicreportNuisanceImageModFunc(func(ctx context.Context, o *PublicreportNuisanceImageTemplate) { + o.r.Image = nil + }) +} + +func (m publicreportNuisanceImageMods) WithNuisance(rel *PublicreportNuisanceTemplate) PublicreportNuisanceImageMod { + return PublicreportNuisanceImageModFunc(func(ctx context.Context, o *PublicreportNuisanceImageTemplate) { + o.r.Nuisance = &publicreportNuisanceImageRNuisanceR{ + o: rel, + } + }) +} + +func (m publicreportNuisanceImageMods) WithNewNuisance(mods ...PublicreportNuisanceMod) PublicreportNuisanceImageMod { + return PublicreportNuisanceImageModFunc(func(ctx context.Context, o *PublicreportNuisanceImageTemplate) { + related := o.f.NewPublicreportNuisanceWithContext(ctx, mods...) + + m.WithNuisance(related).Apply(ctx, o) + }) +} + +func (m publicreportNuisanceImageMods) WithExistingNuisance(em *models.PublicreportNuisance) PublicreportNuisanceImageMod { + return PublicreportNuisanceImageModFunc(func(ctx context.Context, o *PublicreportNuisanceImageTemplate) { + o.r.Nuisance = &publicreportNuisanceImageRNuisanceR{ + o: o.f.FromExistingPublicreportNuisance(em), + } + }) +} + +func (m publicreportNuisanceImageMods) WithoutNuisance() PublicreportNuisanceImageMod { + return PublicreportNuisanceImageModFunc(func(ctx context.Context, o *PublicreportNuisanceImageTemplate) { + o.r.Nuisance = nil + }) +} diff --git a/db/migrations/00049_publicreport_nuisance_h3cell.sql b/db/migrations/00049_publicreport_nuisance_h3cell.sql new file mode 100644 index 00000000..3a098aa2 --- /dev/null +++ b/db/migrations/00049_publicreport_nuisance_h3cell.sql @@ -0,0 +1,12 @@ +-- +goose Up +ALTER TABLE publicreport.nuisance ADD COLUMN h3cell h3index; +ALTER TABLE publicreport.nuisance ADD COLUMN organization_id INTEGER REFERENCES organization(id); +CREATE TABLE publicreport.nuisance_image ( + image_id INTEGER NOT NULL REFERENCES publicreport.image(id), + nuisance_id INTEGER NOT NULL REFERENCES publicreport.nuisance(id), + PRIMARY KEY (image_id, nuisance_id) +); +-- +goose Down +DROP TABLE publicreport.nuisance_image; +ALTER TABLE publicreport.nuisance DROP COLUMN h3cell; +ALTER TABLE publicreport.nuisance DROP COLUMN organization_id; diff --git a/db/models/bob_counts.bob.go b/db/models/bob_counts.bob.go index 219db03a..d8760c06 100644 --- a/db/models/bob_counts.bob.go +++ b/db/models/bob_counts.bob.go @@ -21,62 +21,66 @@ var ( ) type preloadCounts struct { - ArcgisUser arcgisuserCountPreloader - CommsEmailContact commsEmailContactCountPreloader - CommsEmailTemplate commsEmailTemplateCountPreloader - CommsPhone commsPhoneCountPreloader - NoteAudio noteAudioCountPreloader - NoteImage noteImageCountPreloader - Organization organizationCountPreloader - PublicreportImage publicreportImageCountPreloader - PublicreportPool publicreportPoolCountPreloader - PublicreportQuick publicreportQuickCountPreloader - User userCountPreloader + ArcgisUser arcgisuserCountPreloader + CommsEmailContact commsEmailContactCountPreloader + CommsEmailTemplate commsEmailTemplateCountPreloader + CommsPhone commsPhoneCountPreloader + NoteAudio noteAudioCountPreloader + NoteImage noteImageCountPreloader + Organization organizationCountPreloader + PublicreportImage publicreportImageCountPreloader + PublicreportNuisance publicreportNuisanceCountPreloader + PublicreportPool publicreportPoolCountPreloader + PublicreportQuick publicreportQuickCountPreloader + User userCountPreloader } func getPreloadCount() preloadCounts { return preloadCounts{ - ArcgisUser: buildArcgisUserCountPreloader(), - CommsEmailContact: buildCommsEmailContactCountPreloader(), - CommsEmailTemplate: buildCommsEmailTemplateCountPreloader(), - CommsPhone: buildCommsPhoneCountPreloader(), - NoteAudio: buildNoteAudioCountPreloader(), - NoteImage: buildNoteImageCountPreloader(), - Organization: buildOrganizationCountPreloader(), - PublicreportImage: buildPublicreportImageCountPreloader(), - PublicreportPool: buildPublicreportPoolCountPreloader(), - PublicreportQuick: buildPublicreportQuickCountPreloader(), - User: buildUserCountPreloader(), + ArcgisUser: buildArcgisUserCountPreloader(), + CommsEmailContact: buildCommsEmailContactCountPreloader(), + CommsEmailTemplate: buildCommsEmailTemplateCountPreloader(), + CommsPhone: buildCommsPhoneCountPreloader(), + NoteAudio: buildNoteAudioCountPreloader(), + NoteImage: buildNoteImageCountPreloader(), + Organization: buildOrganizationCountPreloader(), + PublicreportImage: buildPublicreportImageCountPreloader(), + PublicreportNuisance: buildPublicreportNuisanceCountPreloader(), + PublicreportPool: buildPublicreportPoolCountPreloader(), + PublicreportQuick: buildPublicreportQuickCountPreloader(), + User: buildUserCountPreloader(), } } type thenLoadCounts[Q orm.Loadable] struct { - ArcgisUser arcgisuserCountThenLoader[Q] - CommsEmailContact commsEmailContactCountThenLoader[Q] - CommsEmailTemplate commsEmailTemplateCountThenLoader[Q] - CommsPhone commsPhoneCountThenLoader[Q] - NoteAudio noteAudioCountThenLoader[Q] - NoteImage noteImageCountThenLoader[Q] - Organization organizationCountThenLoader[Q] - PublicreportImage publicreportImageCountThenLoader[Q] - PublicreportPool publicreportPoolCountThenLoader[Q] - PublicreportQuick publicreportQuickCountThenLoader[Q] - User userCountThenLoader[Q] + ArcgisUser arcgisuserCountThenLoader[Q] + CommsEmailContact commsEmailContactCountThenLoader[Q] + CommsEmailTemplate commsEmailTemplateCountThenLoader[Q] + CommsPhone commsPhoneCountThenLoader[Q] + NoteAudio noteAudioCountThenLoader[Q] + NoteImage noteImageCountThenLoader[Q] + Organization organizationCountThenLoader[Q] + PublicreportImage publicreportImageCountThenLoader[Q] + PublicreportNuisance publicreportNuisanceCountThenLoader[Q] + PublicreportPool publicreportPoolCountThenLoader[Q] + PublicreportQuick publicreportQuickCountThenLoader[Q] + User userCountThenLoader[Q] } func getThenLoadCount[Q orm.Loadable]() thenLoadCounts[Q] { return thenLoadCounts[Q]{ - ArcgisUser: buildArcgisUserCountThenLoader[Q](), - CommsEmailContact: buildCommsEmailContactCountThenLoader[Q](), - CommsEmailTemplate: buildCommsEmailTemplateCountThenLoader[Q](), - CommsPhone: buildCommsPhoneCountThenLoader[Q](), - NoteAudio: buildNoteAudioCountThenLoader[Q](), - NoteImage: buildNoteImageCountThenLoader[Q](), - Organization: buildOrganizationCountThenLoader[Q](), - PublicreportImage: buildPublicreportImageCountThenLoader[Q](), - PublicreportPool: buildPublicreportPoolCountThenLoader[Q](), - PublicreportQuick: buildPublicreportQuickCountThenLoader[Q](), - User: buildUserCountThenLoader[Q](), + ArcgisUser: buildArcgisUserCountThenLoader[Q](), + CommsEmailContact: buildCommsEmailContactCountThenLoader[Q](), + CommsEmailTemplate: buildCommsEmailTemplateCountThenLoader[Q](), + CommsPhone: buildCommsPhoneCountThenLoader[Q](), + NoteAudio: buildNoteAudioCountThenLoader[Q](), + NoteImage: buildNoteImageCountThenLoader[Q](), + Organization: buildOrganizationCountThenLoader[Q](), + PublicreportImage: buildPublicreportImageCountThenLoader[Q](), + PublicreportNuisance: buildPublicreportNuisanceCountThenLoader[Q](), + PublicreportPool: buildPublicreportPoolCountThenLoader[Q](), + PublicreportQuick: buildPublicreportQuickCountThenLoader[Q](), + User: buildUserCountThenLoader[Q](), } } diff --git a/db/models/bob_joins.bob.go b/db/models/bob_joins.bob.go index f34bc98e..d802a175 100644 --- a/db/models/bob_joins.bob.go +++ b/db/models/bob_joins.bob.go @@ -84,6 +84,7 @@ type joins[Q dialect.Joinable] struct { PublicreportImages joinSet[publicreportImageJoins[Q]] PublicreportImageExifs joinSet[publicreportImageExifJoins[Q]] PublicreportNuisances joinSet[publicreportNuisanceJoins[Q]] + PublicreportNuisanceImages joinSet[publicreportNuisanceImageJoins[Q]] PublicreportPools joinSet[publicreportPoolJoins[Q]] PublicreportPoolImages joinSet[publicreportPoolImageJoins[Q]] PublicreportQuicks joinSet[publicreportQuickJoins[Q]] @@ -153,6 +154,7 @@ func getJoins[Q dialect.Joinable]() joins[Q] { PublicreportImages: buildJoinSet[publicreportImageJoins[Q]](PublicreportImages.Columns, buildPublicreportImageJoins), PublicreportImageExifs: buildJoinSet[publicreportImageExifJoins[Q]](PublicreportImageExifs.Columns, buildPublicreportImageExifJoins), PublicreportNuisances: buildJoinSet[publicreportNuisanceJoins[Q]](PublicreportNuisances.Columns, buildPublicreportNuisanceJoins), + PublicreportNuisanceImages: buildJoinSet[publicreportNuisanceImageJoins[Q]](PublicreportNuisanceImages.Columns, buildPublicreportNuisanceImageJoins), PublicreportPools: buildJoinSet[publicreportPoolJoins[Q]](PublicreportPools.Columns, buildPublicreportPoolJoins), PublicreportPoolImages: buildJoinSet[publicreportPoolImageJoins[Q]](PublicreportPoolImages.Columns, buildPublicreportPoolImageJoins), PublicreportQuicks: buildJoinSet[publicreportQuickJoins[Q]](PublicreportQuicks.Columns, buildPublicreportQuickJoins), diff --git a/db/models/bob_loaders.bob.go b/db/models/bob_loaders.bob.go index b0d4b698..03e10c69 100644 --- a/db/models/bob_loaders.bob.go +++ b/db/models/bob_loaders.bob.go @@ -69,6 +69,7 @@ type preloaders struct { PublicreportImage publicreportImagePreloader PublicreportImageExif publicreportImageExifPreloader PublicreportNuisance publicreportNuisancePreloader + PublicreportNuisanceImage publicreportNuisanceImagePreloader PublicreportPool publicreportPoolPreloader PublicreportPoolImage publicreportPoolImagePreloader PublicreportQuick publicreportQuickPreloader @@ -130,6 +131,7 @@ func getPreloaders() preloaders { PublicreportImage: buildPublicreportImagePreloader(), PublicreportImageExif: buildPublicreportImageExifPreloader(), PublicreportNuisance: buildPublicreportNuisancePreloader(), + PublicreportNuisanceImage: buildPublicreportNuisanceImagePreloader(), PublicreportPool: buildPublicreportPoolPreloader(), PublicreportPoolImage: buildPublicreportPoolImagePreloader(), PublicreportQuick: buildPublicreportQuickPreloader(), @@ -197,6 +199,7 @@ type thenLoaders[Q orm.Loadable] struct { PublicreportImage publicreportImageThenLoader[Q] PublicreportImageExif publicreportImageExifThenLoader[Q] PublicreportNuisance publicreportNuisanceThenLoader[Q] + PublicreportNuisanceImage publicreportNuisanceImageThenLoader[Q] PublicreportPool publicreportPoolThenLoader[Q] PublicreportPoolImage publicreportPoolImageThenLoader[Q] PublicreportQuick publicreportQuickThenLoader[Q] @@ -258,6 +261,7 @@ func getThenLoaders[Q orm.Loadable]() thenLoaders[Q] { PublicreportImage: buildPublicreportImageThenLoader[Q](), PublicreportImageExif: buildPublicreportImageExifThenLoader[Q](), PublicreportNuisance: buildPublicreportNuisanceThenLoader[Q](), + PublicreportNuisanceImage: buildPublicreportNuisanceImageThenLoader[Q](), PublicreportPool: buildPublicreportPoolThenLoader[Q](), PublicreportPoolImage: buildPublicreportPoolImageThenLoader[Q](), PublicreportQuick: buildPublicreportQuickThenLoader[Q](), diff --git a/db/models/bob_where.bob.go b/db/models/bob_where.bob.go index 171db52c..924ae626 100644 --- a/db/models/bob_where.bob.go +++ b/db/models/bob_where.bob.go @@ -72,6 +72,7 @@ func Where[Q psql.Filterable]() struct { PublicreportImages publicreportImageWhere[Q] PublicreportImageExifs publicreportImageExifWhere[Q] PublicreportNuisances publicreportNuisanceWhere[Q] + PublicreportNuisanceImages publicreportNuisanceImageWhere[Q] PublicreportPools publicreportPoolWhere[Q] PublicreportPoolImages publicreportPoolImageWhere[Q] PublicreportQuicks publicreportQuickWhere[Q] @@ -139,6 +140,7 @@ func Where[Q psql.Filterable]() struct { PublicreportImages publicreportImageWhere[Q] PublicreportImageExifs publicreportImageExifWhere[Q] PublicreportNuisances publicreportNuisanceWhere[Q] + PublicreportNuisanceImages publicreportNuisanceImageWhere[Q] PublicreportPools publicreportPoolWhere[Q] PublicreportPoolImages publicreportPoolImageWhere[Q] PublicreportQuicks publicreportQuickWhere[Q] @@ -205,6 +207,7 @@ func Where[Q psql.Filterable]() struct { PublicreportImages: buildPublicreportImageWhere[Q](PublicreportImages.Columns), PublicreportImageExifs: buildPublicreportImageExifWhere[Q](PublicreportImageExifs.Columns), PublicreportNuisances: buildPublicreportNuisanceWhere[Q](PublicreportNuisances.Columns), + PublicreportNuisanceImages: buildPublicreportNuisanceImageWhere[Q](PublicreportNuisanceImages.Columns), PublicreportPools: buildPublicreportPoolWhere[Q](PublicreportPools.Columns), PublicreportPoolImages: buildPublicreportPoolImageWhere[Q](PublicreportPoolImages.Columns), PublicreportQuicks: buildPublicreportQuickWhere[Q](PublicreportQuicks.Columns), diff --git a/db/models/publicreport.image.bob.go b/db/models/publicreport.image.bob.go index c0601c2b..939d4b23 100644 --- a/db/models/publicreport.image.bob.go +++ b/db/models/publicreport.image.bob.go @@ -57,6 +57,7 @@ type PublicreportImagesQuery = *psql.ViewQuery[*PublicreportImage, PublicreportI // publicreportImageR is where relationships are stored. type publicreportImageR struct { ImageExifs PublicreportImageExifSlice // publicreport.image_exif.image_exif_image_id_fkey + Nuisances PublicreportNuisanceSlice // publicreport.nuisance_image.nuisance_image_image_id_fkeypublicreport.nuisance_image.nuisance_image_nuisance_id_fkey Pools PublicreportPoolSlice // publicreport.pool_image.pool_image_image_id_fkeypublicreport.pool_image.pool_image_pool_id_fkey Quicks PublicreportQuickSlice // publicreport.quick_image.quick_image_image_id_fkeypublicreport.quick_image.quick_image_quick_id_fkey } @@ -563,6 +564,35 @@ func (os PublicreportImageSlice) ImageExifs(mods ...bob.Mod[*dialect.SelectQuery )...) } +// Nuisances starts a query for related objects on publicreport.nuisance +func (o *PublicreportImage) Nuisances(mods ...bob.Mod[*dialect.SelectQuery]) PublicreportNuisancesQuery { + return PublicreportNuisances.Query(append(mods, + sm.InnerJoin(PublicreportNuisanceImages.NameAs()).On( + PublicreportNuisances.Columns.ID.EQ(PublicreportNuisanceImages.Columns.NuisanceID)), + sm.Where(PublicreportNuisanceImages.Columns.ImageID.EQ(psql.Arg(o.ID))), + )...) +} + +func (os PublicreportImageSlice) Nuisances(mods ...bob.Mod[*dialect.SelectQuery]) PublicreportNuisancesQuery { + 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 PublicreportNuisances.Query(append(mods, + sm.InnerJoin(PublicreportNuisanceImages.NameAs()).On( + PublicreportNuisances.Columns.ID.EQ(PublicreportNuisanceImages.Columns.NuisanceID), + ), + sm.Where(psql.Group(PublicreportNuisanceImages.Columns.ImageID).OP("IN", PKArgExpr)), + )...) +} + // Pools starts a query for related objects on publicreport.pool func (o *PublicreportImage) Pools(mods ...bob.Mod[*dialect.SelectQuery]) PublicreportPoolsQuery { return PublicreportPools.Query(append(mods, @@ -689,6 +719,71 @@ func (publicreportImage0 *PublicreportImage) AttachImageExifs(ctx context.Contex return nil } +func attachPublicreportImageNuisances0(ctx context.Context, exec bob.Executor, count int, publicreportImage0 *PublicreportImage, publicreportNuisances2 PublicreportNuisanceSlice) (PublicreportNuisanceImageSlice, error) { + setters := make([]*PublicreportNuisanceImageSetter, count) + for i := range count { + setters[i] = &PublicreportNuisanceImageSetter{ + ImageID: omit.From(publicreportImage0.ID), + NuisanceID: omit.From(publicreportNuisances2[i].ID), + } + } + + publicreportNuisanceImages1, err := PublicreportNuisanceImages.Insert(bob.ToMods(setters...)).All(ctx, exec) + if err != nil { + return nil, fmt.Errorf("attachPublicreportImageNuisances0: %w", err) + } + + return publicreportNuisanceImages1, nil +} + +func (publicreportImage0 *PublicreportImage) InsertNuisances(ctx context.Context, exec bob.Executor, related ...*PublicreportNuisanceSetter) error { + if len(related) == 0 { + return nil + } + + var err error + + inserted, err := PublicreportNuisances.Insert(bob.ToMods(related...)).All(ctx, exec) + if err != nil { + return fmt.Errorf("inserting related objects: %w", err) + } + publicreportNuisances2 := PublicreportNuisanceSlice(inserted) + + _, err = attachPublicreportImageNuisances0(ctx, exec, len(related), publicreportImage0, publicreportNuisances2) + if err != nil { + return err + } + + publicreportImage0.R.Nuisances = append(publicreportImage0.R.Nuisances, publicreportNuisances2...) + + for _, rel := range publicreportNuisances2 { + rel.R.Images = append(rel.R.Images, publicreportImage0) + } + return nil +} + +func (publicreportImage0 *PublicreportImage) AttachNuisances(ctx context.Context, exec bob.Executor, related ...*PublicreportNuisance) error { + if len(related) == 0 { + return nil + } + + var err error + publicreportNuisances2 := PublicreportNuisanceSlice(related) + + _, err = attachPublicreportImageNuisances0(ctx, exec, len(related), publicreportImage0, publicreportNuisances2) + if err != nil { + return err + } + + publicreportImage0.R.Nuisances = append(publicreportImage0.R.Nuisances, publicreportNuisances2...) + + for _, rel := range related { + rel.R.Images = append(rel.R.Images, publicreportImage0) + } + + return nil +} + func attachPublicreportImagePools0(ctx context.Context, exec bob.Executor, count int, publicreportImage0 *PublicreportImage, publicreportPools2 PublicreportPoolSlice) (PublicreportPoolImageSlice, error) { setters := make([]*PublicreportPoolImageSetter, count) for i := range count { @@ -869,6 +964,20 @@ func (o *PublicreportImage) Preload(name string, retrieved any) error { } } return nil + case "Nuisances": + rels, ok := retrieved.(PublicreportNuisanceSlice) + if !ok { + return fmt.Errorf("publicreportImage cannot load %T as %q", retrieved, name) + } + + o.R.Nuisances = rels + + for _, rel := range rels { + if rel != nil { + rel.R.Images = PublicreportImageSlice{o} + } + } + return nil case "Pools": rels, ok := retrieved.(PublicreportPoolSlice) if !ok { @@ -910,6 +1019,7 @@ func buildPublicreportImagePreloader() publicreportImagePreloader { type publicreportImageThenLoader[Q orm.Loadable] struct { ImageExifs func(...bob.Mod[*dialect.SelectQuery]) orm.Loader[Q] + Nuisances func(...bob.Mod[*dialect.SelectQuery]) orm.Loader[Q] Pools func(...bob.Mod[*dialect.SelectQuery]) orm.Loader[Q] Quicks func(...bob.Mod[*dialect.SelectQuery]) orm.Loader[Q] } @@ -918,6 +1028,9 @@ func buildPublicreportImageThenLoader[Q orm.Loadable]() publicreportImageThenLoa type ImageExifsLoadInterface interface { LoadImageExifs(context.Context, bob.Executor, ...bob.Mod[*dialect.SelectQuery]) error } + type NuisancesLoadInterface interface { + LoadNuisances(context.Context, bob.Executor, ...bob.Mod[*dialect.SelectQuery]) error + } type PoolsLoadInterface interface { LoadPools(context.Context, bob.Executor, ...bob.Mod[*dialect.SelectQuery]) error } @@ -932,6 +1045,12 @@ func buildPublicreportImageThenLoader[Q orm.Loadable]() publicreportImageThenLoa return retrieved.LoadImageExifs(ctx, exec, mods...) }, ), + Nuisances: thenLoadBuilder[Q]( + "Nuisances", + func(ctx context.Context, exec bob.Executor, retrieved NuisancesLoadInterface, mods ...bob.Mod[*dialect.SelectQuery]) error { + return retrieved.LoadNuisances(ctx, exec, mods...) + }, + ), Pools: thenLoadBuilder[Q]( "Pools", func(ctx context.Context, exec bob.Executor, retrieved PoolsLoadInterface, mods ...bob.Mod[*dialect.SelectQuery]) error { @@ -1008,6 +1127,87 @@ func (os PublicreportImageSlice) LoadImageExifs(ctx context.Context, exec bob.Ex return nil } +// LoadNuisances loads the publicreportImage's Nuisances into the .R struct +func (o *PublicreportImage) LoadNuisances(ctx context.Context, exec bob.Executor, mods ...bob.Mod[*dialect.SelectQuery]) error { + if o == nil { + return nil + } + + // Reset the relationship + o.R.Nuisances = nil + + related, err := o.Nuisances(mods...).All(ctx, exec) + if err != nil { + return err + } + + for _, rel := range related { + rel.R.Images = PublicreportImageSlice{o} + } + + o.R.Nuisances = related + return nil +} + +// LoadNuisances loads the publicreportImage's Nuisances into the .R struct +func (os PublicreportImageSlice) LoadNuisances(ctx context.Context, exec bob.Executor, mods ...bob.Mod[*dialect.SelectQuery]) error { + if len(os) == 0 { + return nil + } + + // since we are changing the columns, we need to check if the original columns were set or add the defaults + sq := dialect.SelectQuery{} + for _, mod := range mods { + mod.Apply(&sq) + } + + if len(sq.SelectList.Columns) == 0 { + mods = append(mods, sm.Columns(PublicreportNuisances.Columns)) + } + + q := os.Nuisances(append( + mods, + sm.Columns(PublicreportNuisanceImages.Columns.ImageID.As("related_publicreport.image.ID")), + )...) + + IDSlice := []int32{} + + mapper := scan.Mod(scan.StructMapper[*PublicreportNuisance](), func(ctx context.Context, cols []string) (scan.BeforeFunc, func(any, any) error) { + return func(row *scan.Row) (any, error) { + IDSlice = append(IDSlice, *new(int32)) + row.ScheduleScanByName("related_publicreport.image.ID", &IDSlice[len(IDSlice)-1]) + + return nil, nil + }, + func(any, any) error { + return nil + } + }) + + publicreportNuisances, err := bob.Allx[bob.SliceTransformer[*PublicreportNuisance, PublicreportNuisanceSlice]](ctx, exec, q, mapper) + if err != nil { + return err + } + + for _, o := range os { + o.R.Nuisances = nil + } + + for _, o := range os { + for i, rel := range publicreportNuisances { + if !(o.ID == IDSlice[i]) { + continue + } + + rel.R.Images = append(rel.R.Images, o) + + o.R.Nuisances = append(o.R.Nuisances, rel) + } + } + + return nil +} + // LoadPools loads the publicreportImage's Pools into the .R struct func (o *PublicreportImage) LoadPools(ctx context.Context, exec bob.Executor, mods ...bob.Mod[*dialect.SelectQuery]) error { if o == nil { @@ -1173,6 +1373,7 @@ func (os PublicreportImageSlice) LoadQuicks(ctx context.Context, exec bob.Execut // publicreportImageC is where relationship counts are stored. type publicreportImageC struct { ImageExifs *int64 + Nuisances *int64 Pools *int64 Quicks *int64 } @@ -1186,6 +1387,8 @@ func (o *PublicreportImage) PreloadCount(name string, count int64) error { switch name { case "ImageExifs": o.C.ImageExifs = &count + case "Nuisances": + o.C.Nuisances = &count case "Pools": o.C.Pools = &count case "Quicks": @@ -1196,6 +1399,7 @@ func (o *PublicreportImage) PreloadCount(name string, count int64) error { type publicreportImageCountPreloader struct { ImageExifs func(...bob.Mod[*dialect.SelectQuery]) psql.Preloader + Nuisances func(...bob.Mod[*dialect.SelectQuery]) psql.Preloader Pools func(...bob.Mod[*dialect.SelectQuery]) psql.Preloader Quicks func(...bob.Mod[*dialect.SelectQuery]) psql.Preloader } @@ -1219,6 +1423,26 @@ func buildPublicreportImageCountPreloader() publicreportImageCountPreloader { return psql.Group(psql.Select(subqueryMods...).Expression) }) }, + Nuisances: func(mods ...bob.Mod[*dialect.SelectQuery]) psql.Preloader { + return countPreloader[*PublicreportImage]("Nuisances", func(parent string) bob.Expression { + // Build a correlated subquery: (SELECT COUNT(*) FROM related WHERE fk = parent.pk) + if parent == "" { + parent = PublicreportImages.Alias() + } + + subqueryMods := []bob.Mod[*dialect.SelectQuery]{ + sm.Columns(psql.Raw("count(*)")), + + sm.From(PublicreportNuisanceImages.Name()), + sm.Where(psql.Quote(PublicreportNuisanceImages.Alias(), "image_id").EQ(psql.Quote(parent, "id"))), + sm.InnerJoin(PublicreportNuisances.Name()).On( + psql.Quote(PublicreportNuisances.Alias(), "id").EQ(psql.Quote(PublicreportNuisanceImages.Alias(), "nuisance_id")), + ), + } + subqueryMods = append(subqueryMods, mods...) + return psql.Group(psql.Select(subqueryMods...).Expression) + }) + }, Pools: func(mods ...bob.Mod[*dialect.SelectQuery]) psql.Preloader { return countPreloader[*PublicreportImage]("Pools", func(parent string) bob.Expression { // Build a correlated subquery: (SELECT COUNT(*) FROM related WHERE fk = parent.pk) @@ -1264,6 +1488,7 @@ func buildPublicreportImageCountPreloader() publicreportImageCountPreloader { type publicreportImageCountThenLoader[Q orm.Loadable] struct { ImageExifs func(...bob.Mod[*dialect.SelectQuery]) orm.Loader[Q] + Nuisances func(...bob.Mod[*dialect.SelectQuery]) orm.Loader[Q] Pools func(...bob.Mod[*dialect.SelectQuery]) orm.Loader[Q] Quicks func(...bob.Mod[*dialect.SelectQuery]) orm.Loader[Q] } @@ -1272,6 +1497,9 @@ func buildPublicreportImageCountThenLoader[Q orm.Loadable]() publicreportImageCo type ImageExifsCountInterface interface { LoadCountImageExifs(context.Context, bob.Executor, ...bob.Mod[*dialect.SelectQuery]) error } + type NuisancesCountInterface interface { + LoadCountNuisances(context.Context, bob.Executor, ...bob.Mod[*dialect.SelectQuery]) error + } type PoolsCountInterface interface { LoadCountPools(context.Context, bob.Executor, ...bob.Mod[*dialect.SelectQuery]) error } @@ -1286,6 +1514,12 @@ func buildPublicreportImageCountThenLoader[Q orm.Loadable]() publicreportImageCo return retrieved.LoadCountImageExifs(ctx, exec, mods...) }, ), + Nuisances: countThenLoadBuilder[Q]( + "Nuisances", + func(ctx context.Context, exec bob.Executor, retrieved NuisancesCountInterface, mods ...bob.Mod[*dialect.SelectQuery]) error { + return retrieved.LoadCountNuisances(ctx, exec, mods...) + }, + ), Pools: countThenLoadBuilder[Q]( "Pools", func(ctx context.Context, exec bob.Executor, retrieved PoolsCountInterface, mods ...bob.Mod[*dialect.SelectQuery]) error { @@ -1331,6 +1565,36 @@ func (os PublicreportImageSlice) LoadCountImageExifs(ctx context.Context, exec b return nil } +// LoadCountNuisances loads the count of Nuisances into the C struct +func (o *PublicreportImage) LoadCountNuisances(ctx context.Context, exec bob.Executor, mods ...bob.Mod[*dialect.SelectQuery]) error { + if o == nil { + return nil + } + + count, err := o.Nuisances(mods...).Count(ctx, exec) + if err != nil { + return err + } + + o.C.Nuisances = &count + return nil +} + +// LoadCountNuisances loads the count of Nuisances for a slice +func (os PublicreportImageSlice) LoadCountNuisances(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.LoadCountNuisances(ctx, exec, mods...); err != nil { + return err + } + } + + return nil +} + // LoadCountPools loads the count of Pools into the C struct func (o *PublicreportImage) LoadCountPools(ctx context.Context, exec bob.Executor, mods ...bob.Mod[*dialect.SelectQuery]) error { if o == nil { @@ -1394,6 +1658,7 @@ func (os PublicreportImageSlice) LoadCountQuicks(ctx context.Context, exec bob.E type publicreportImageJoins[Q dialect.Joinable] struct { typ string ImageExifs modAs[Q, publicreportImageExifColumns] + Nuisances modAs[Q, publicreportNuisanceColumns] Pools modAs[Q, publicreportPoolColumns] Quicks modAs[Q, publicreportQuickColumns] } @@ -1419,6 +1684,28 @@ func buildPublicreportImageJoins[Q dialect.Joinable](cols publicreportImageColum return mods }, }, + Nuisances: modAs[Q, publicreportNuisanceColumns]{ + c: PublicreportNuisances.Columns, + f: func(to publicreportNuisanceColumns) bob.Mod[Q] { + random := strconv.FormatInt(randInt(), 10) + mods := make(mods.QueryMods[Q], 0, 2) + + { + to := PublicreportNuisanceImages.Columns.AliasedAs(PublicreportNuisanceImages.Columns.Alias() + random) + mods = append(mods, dialect.Join[Q](typ, PublicreportNuisanceImages.Name().As(to.Alias())).On( + to.ImageID.EQ(cols.ID), + )) + } + { + cols := PublicreportNuisanceImages.Columns.AliasedAs(PublicreportNuisanceImages.Columns.Alias() + random) + mods = append(mods, dialect.Join[Q](typ, PublicreportNuisances.Name().As(to.Alias())).On( + to.ID.EQ(cols.NuisanceID), + )) + } + + return mods + }, + }, Pools: modAs[Q, publicreportPoolColumns]{ c: PublicreportPools.Columns, f: func(to publicreportPoolColumns) bob.Mod[Q] { diff --git a/db/models/publicreport.nuisance.bob.go b/db/models/publicreport.nuisance.bob.go index 22147967..c832799b 100644 --- a/db/models/publicreport.nuisance.bob.go +++ b/db/models/publicreport.nuisance.bob.go @@ -7,6 +7,7 @@ import ( "context" "fmt" "io" + "strconv" "time" "github.com/Gleipnir-Technology/bob" @@ -23,6 +24,7 @@ import ( "github.com/aarondl/opt/null" "github.com/aarondl/opt/omit" "github.com/aarondl/opt/omitnull" + "github.com/stephenafamo/scan" ) // PublicreportNuisance is an object representing the database table. @@ -44,8 +46,11 @@ type PublicreportNuisance struct { Status enums.PublicreportReportstatustype `db:"status" ` OrganizationID null.Val[int32] `db:"organization_id" ` SourceGutter bool `db:"source_gutter" ` + H3cell null.Val[string] `db:"h3cell" ` R publicreportNuisanceR `db:"-" ` + + C publicreportNuisanceC `db:"-" ` } // PublicreportNuisanceSlice is an alias for a slice of pointers to PublicreportNuisance. @@ -60,13 +65,14 @@ type PublicreportNuisancesQuery = *psql.ViewQuery[*PublicreportNuisance, Publicr // publicreportNuisanceR is where relationships are stored. type publicreportNuisanceR struct { - Organization *Organization // publicreport.nuisance.nuisance_organization_id_fkey + Organization *Organization // publicreport.nuisance.nuisance_organization_id_fkey + Images PublicreportImageSlice // publicreport.nuisance_image.nuisance_image_image_id_fkeypublicreport.nuisance_image.nuisance_image_nuisance_id_fkey } func buildPublicreportNuisanceColumns(alias string) publicreportNuisanceColumns { return publicreportNuisanceColumns{ ColumnsExpr: expr.NewColumnsExpr( - "id", "additional_info", "created", "duration", "source_location", "source_container", "source_description", "source_stagnant", "public_id", "reporter_email", "reporter_name", "reporter_phone", "address", "location", "status", "organization_id", "source_gutter", + "id", "additional_info", "created", "duration", "source_location", "source_container", "source_description", "source_stagnant", "public_id", "reporter_email", "reporter_name", "reporter_phone", "address", "location", "status", "organization_id", "source_gutter", "h3cell", ).WithParent("publicreport.nuisance"), tableAlias: alias, ID: psql.Quote(alias, "id"), @@ -86,6 +92,7 @@ func buildPublicreportNuisanceColumns(alias string) publicreportNuisanceColumns Status: psql.Quote(alias, "status"), OrganizationID: psql.Quote(alias, "organization_id"), SourceGutter: psql.Quote(alias, "source_gutter"), + H3cell: psql.Quote(alias, "h3cell"), } } @@ -109,6 +116,7 @@ type publicreportNuisanceColumns struct { Status psql.Expression OrganizationID psql.Expression SourceGutter psql.Expression + H3cell psql.Expression } func (c publicreportNuisanceColumns) Alias() string { @@ -140,10 +148,11 @@ type PublicreportNuisanceSetter struct { Status omit.Val[enums.PublicreportReportstatustype] `db:"status" ` OrganizationID omitnull.Val[int32] `db:"organization_id" ` SourceGutter omit.Val[bool] `db:"source_gutter" ` + H3cell omitnull.Val[string] `db:"h3cell" ` } func (s PublicreportNuisanceSetter) SetColumns() []string { - vals := make([]string, 0, 17) + vals := make([]string, 0, 18) if s.ID.IsValue() { vals = append(vals, "id") } @@ -195,6 +204,9 @@ func (s PublicreportNuisanceSetter) SetColumns() []string { if s.SourceGutter.IsValue() { vals = append(vals, "source_gutter") } + if !s.H3cell.IsUnset() { + vals = append(vals, "h3cell") + } return vals } @@ -250,6 +262,9 @@ func (s PublicreportNuisanceSetter) Overwrite(t *PublicreportNuisance) { if s.SourceGutter.IsValue() { t.SourceGutter = s.SourceGutter.MustGet() } + if !s.H3cell.IsUnset() { + t.H3cell = s.H3cell.MustGetNull() + } } func (s *PublicreportNuisanceSetter) Apply(q *dialect.InsertQuery) { @@ -258,7 +273,7 @@ func (s *PublicreportNuisanceSetter) 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, 17) + vals := make([]bob.Expression, 18) if s.ID.IsValue() { vals[0] = psql.Arg(s.ID.MustGet()) } else { @@ -361,6 +376,12 @@ func (s *PublicreportNuisanceSetter) Apply(q *dialect.InsertQuery) { vals[16] = psql.Raw("DEFAULT") } + if !s.H3cell.IsUnset() { + vals[17] = psql.Arg(s.H3cell.MustGetNull()) + } else { + vals[17] = psql.Raw("DEFAULT") + } + return bob.ExpressSlice(ctx, w, d, start, vals, "", ", ", "") })) } @@ -370,7 +391,7 @@ func (s PublicreportNuisanceSetter) UpdateMod() bob.Mod[*dialect.UpdateQuery] { } func (s PublicreportNuisanceSetter) Expressions(prefix ...string) []bob.Expression { - exprs := make([]bob.Expression, 0, 17) + exprs := make([]bob.Expression, 0, 18) if s.ID.IsValue() { exprs = append(exprs, expr.Join{Sep: " = ", Exprs: []bob.Expression{ @@ -491,6 +512,13 @@ func (s PublicreportNuisanceSetter) Expressions(prefix ...string) []bob.Expressi }}) } + if !s.H3cell.IsUnset() { + exprs = append(exprs, expr.Join{Sep: " = ", Exprs: []bob.Expression{ + psql.Quote(append(prefix, "h3cell")...), + psql.Arg(s.H3cell), + }}) + } + return exprs } @@ -741,6 +769,35 @@ func (os PublicreportNuisanceSlice) Organization(mods ...bob.Mod[*dialect.Select )...) } +// Images starts a query for related objects on publicreport.image +func (o *PublicreportNuisance) Images(mods ...bob.Mod[*dialect.SelectQuery]) PublicreportImagesQuery { + return PublicreportImages.Query(append(mods, + sm.InnerJoin(PublicreportNuisanceImages.NameAs()).On( + PublicreportImages.Columns.ID.EQ(PublicreportNuisanceImages.Columns.ImageID)), + sm.Where(PublicreportNuisanceImages.Columns.NuisanceID.EQ(psql.Arg(o.ID))), + )...) +} + +func (os PublicreportNuisanceSlice) Images(mods ...bob.Mod[*dialect.SelectQuery]) PublicreportImagesQuery { + 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 PublicreportImages.Query(append(mods, + sm.InnerJoin(PublicreportNuisanceImages.NameAs()).On( + PublicreportImages.Columns.ID.EQ(PublicreportNuisanceImages.Columns.ImageID), + ), + sm.Where(psql.Group(PublicreportNuisanceImages.Columns.NuisanceID).OP("IN", PKArgExpr)), + )...) +} + func attachPublicreportNuisanceOrganization0(ctx context.Context, exec bob.Executor, count int, publicreportNuisance0 *PublicreportNuisance, organization1 *Organization) (*PublicreportNuisance, error) { setter := &PublicreportNuisanceSetter{ OrganizationID: omitnull.From(organization1.ID), @@ -789,6 +846,71 @@ func (publicreportNuisance0 *PublicreportNuisance) AttachOrganization(ctx contex return nil } +func attachPublicreportNuisanceImages0(ctx context.Context, exec bob.Executor, count int, publicreportNuisance0 *PublicreportNuisance, publicreportImages2 PublicreportImageSlice) (PublicreportNuisanceImageSlice, error) { + setters := make([]*PublicreportNuisanceImageSetter, count) + for i := range count { + setters[i] = &PublicreportNuisanceImageSetter{ + NuisanceID: omit.From(publicreportNuisance0.ID), + ImageID: omit.From(publicreportImages2[i].ID), + } + } + + publicreportNuisanceImages1, err := PublicreportNuisanceImages.Insert(bob.ToMods(setters...)).All(ctx, exec) + if err != nil { + return nil, fmt.Errorf("attachPublicreportNuisanceImages0: %w", err) + } + + return publicreportNuisanceImages1, nil +} + +func (publicreportNuisance0 *PublicreportNuisance) InsertImages(ctx context.Context, exec bob.Executor, related ...*PublicreportImageSetter) error { + if len(related) == 0 { + return nil + } + + var err error + + inserted, err := PublicreportImages.Insert(bob.ToMods(related...)).All(ctx, exec) + if err != nil { + return fmt.Errorf("inserting related objects: %w", err) + } + publicreportImages2 := PublicreportImageSlice(inserted) + + _, err = attachPublicreportNuisanceImages0(ctx, exec, len(related), publicreportNuisance0, publicreportImages2) + if err != nil { + return err + } + + publicreportNuisance0.R.Images = append(publicreportNuisance0.R.Images, publicreportImages2...) + + for _, rel := range publicreportImages2 { + rel.R.Nuisances = append(rel.R.Nuisances, publicreportNuisance0) + } + return nil +} + +func (publicreportNuisance0 *PublicreportNuisance) AttachImages(ctx context.Context, exec bob.Executor, related ...*PublicreportImage) error { + if len(related) == 0 { + return nil + } + + var err error + publicreportImages2 := PublicreportImageSlice(related) + + _, err = attachPublicreportNuisanceImages0(ctx, exec, len(related), publicreportNuisance0, publicreportImages2) + if err != nil { + return err + } + + publicreportNuisance0.R.Images = append(publicreportNuisance0.R.Images, publicreportImages2...) + + for _, rel := range related { + rel.R.Nuisances = append(rel.R.Nuisances, publicreportNuisance0) + } + + return nil +} + type publicreportNuisanceWhere[Q psql.Filterable] struct { ID psql.WhereMod[Q, int32] AdditionalInfo psql.WhereMod[Q, string] @@ -807,6 +929,7 @@ type publicreportNuisanceWhere[Q psql.Filterable] struct { Status psql.WhereMod[Q, enums.PublicreportReportstatustype] OrganizationID psql.WhereNullMod[Q, int32] SourceGutter psql.WhereMod[Q, bool] + H3cell psql.WhereNullMod[Q, string] } func (publicreportNuisanceWhere[Q]) AliasedAs(alias string) publicreportNuisanceWhere[Q] { @@ -832,6 +955,7 @@ func buildPublicreportNuisanceWhere[Q psql.Filterable](cols publicreportNuisance Status: psql.Where[Q, enums.PublicreportReportstatustype](cols.Status), OrganizationID: psql.WhereNull[Q, int32](cols.OrganizationID), SourceGutter: psql.Where[Q, bool](cols.SourceGutter), + H3cell: psql.WhereNull[Q, string](cols.H3cell), } } @@ -853,6 +977,20 @@ func (o *PublicreportNuisance) Preload(name string, retrieved any) error { rel.R.Nuisances = PublicreportNuisanceSlice{o} } return nil + case "Images": + rels, ok := retrieved.(PublicreportImageSlice) + if !ok { + return fmt.Errorf("publicreportNuisance cannot load %T as %q", retrieved, name) + } + + o.R.Images = rels + + for _, rel := range rels { + if rel != nil { + rel.R.Nuisances = PublicreportNuisanceSlice{o} + } + } + return nil default: return fmt.Errorf("publicreportNuisance has no relationship %q", name) } @@ -882,12 +1020,16 @@ func buildPublicreportNuisancePreloader() publicreportNuisancePreloader { type publicreportNuisanceThenLoader[Q orm.Loadable] struct { Organization func(...bob.Mod[*dialect.SelectQuery]) orm.Loader[Q] + Images func(...bob.Mod[*dialect.SelectQuery]) orm.Loader[Q] } func buildPublicreportNuisanceThenLoader[Q orm.Loadable]() publicreportNuisanceThenLoader[Q] { type OrganizationLoadInterface interface { LoadOrganization(context.Context, bob.Executor, ...bob.Mod[*dialect.SelectQuery]) error } + type ImagesLoadInterface interface { + LoadImages(context.Context, bob.Executor, ...bob.Mod[*dialect.SelectQuery]) error + } return publicreportNuisanceThenLoader[Q]{ Organization: thenLoadBuilder[Q]( @@ -896,6 +1038,12 @@ func buildPublicreportNuisanceThenLoader[Q orm.Loadable]() publicreportNuisanceT return retrieved.LoadOrganization(ctx, exec, mods...) }, ), + Images: thenLoadBuilder[Q]( + "Images", + func(ctx context.Context, exec bob.Executor, retrieved ImagesLoadInterface, mods ...bob.Mod[*dialect.SelectQuery]) error { + return retrieved.LoadImages(ctx, exec, mods...) + }, + ), } } @@ -954,9 +1102,187 @@ func (os PublicreportNuisanceSlice) LoadOrganization(ctx context.Context, exec b return nil } +// LoadImages loads the publicreportNuisance's Images into the .R struct +func (o *PublicreportNuisance) LoadImages(ctx context.Context, exec bob.Executor, mods ...bob.Mod[*dialect.SelectQuery]) error { + if o == nil { + return nil + } + + // Reset the relationship + o.R.Images = nil + + related, err := o.Images(mods...).All(ctx, exec) + if err != nil { + return err + } + + for _, rel := range related { + rel.R.Nuisances = PublicreportNuisanceSlice{o} + } + + o.R.Images = related + return nil +} + +// LoadImages loads the publicreportNuisance's Images into the .R struct +func (os PublicreportNuisanceSlice) LoadImages(ctx context.Context, exec bob.Executor, mods ...bob.Mod[*dialect.SelectQuery]) error { + if len(os) == 0 { + return nil + } + + // since we are changing the columns, we need to check if the original columns were set or add the defaults + sq := dialect.SelectQuery{} + for _, mod := range mods { + mod.Apply(&sq) + } + + if len(sq.SelectList.Columns) == 0 { + mods = append(mods, sm.Columns(PublicreportImages.Columns)) + } + + q := os.Images(append( + mods, + sm.Columns(PublicreportNuisanceImages.Columns.NuisanceID.As("related_publicreport.nuisance.ID")), + )...) + + IDSlice := []int32{} + + mapper := scan.Mod(scan.StructMapper[*PublicreportImage](), func(ctx context.Context, cols []string) (scan.BeforeFunc, func(any, any) error) { + return func(row *scan.Row) (any, error) { + IDSlice = append(IDSlice, *new(int32)) + row.ScheduleScanByName("related_publicreport.nuisance.ID", &IDSlice[len(IDSlice)-1]) + + return nil, nil + }, + func(any, any) error { + return nil + } + }) + + publicreportImages, err := bob.Allx[bob.SliceTransformer[*PublicreportImage, PublicreportImageSlice]](ctx, exec, q, mapper) + if err != nil { + return err + } + + for _, o := range os { + o.R.Images = nil + } + + for _, o := range os { + for i, rel := range publicreportImages { + if !(o.ID == IDSlice[i]) { + continue + } + + rel.R.Nuisances = append(rel.R.Nuisances, o) + + o.R.Images = append(o.R.Images, rel) + } + } + + return nil +} + +// publicreportNuisanceC is where relationship counts are stored. +type publicreportNuisanceC struct { + Images *int64 +} + +// PreloadCount sets a count in the C struct by name +func (o *PublicreportNuisance) PreloadCount(name string, count int64) error { + if o == nil { + return nil + } + + switch name { + case "Images": + o.C.Images = &count + } + return nil +} + +type publicreportNuisanceCountPreloader struct { + Images func(...bob.Mod[*dialect.SelectQuery]) psql.Preloader +} + +func buildPublicreportNuisanceCountPreloader() publicreportNuisanceCountPreloader { + return publicreportNuisanceCountPreloader{ + Images: func(mods ...bob.Mod[*dialect.SelectQuery]) psql.Preloader { + return countPreloader[*PublicreportNuisance]("Images", func(parent string) bob.Expression { + // Build a correlated subquery: (SELECT COUNT(*) FROM related WHERE fk = parent.pk) + if parent == "" { + parent = PublicreportNuisances.Alias() + } + + subqueryMods := []bob.Mod[*dialect.SelectQuery]{ + sm.Columns(psql.Raw("count(*)")), + + sm.From(PublicreportNuisanceImages.Name()), + sm.Where(psql.Quote(PublicreportNuisanceImages.Alias(), "nuisance_id").EQ(psql.Quote(parent, "id"))), + sm.InnerJoin(PublicreportImages.Name()).On( + psql.Quote(PublicreportImages.Alias(), "id").EQ(psql.Quote(PublicreportNuisanceImages.Alias(), "image_id")), + ), + } + subqueryMods = append(subqueryMods, mods...) + return psql.Group(psql.Select(subqueryMods...).Expression) + }) + }, + } +} + +type publicreportNuisanceCountThenLoader[Q orm.Loadable] struct { + Images func(...bob.Mod[*dialect.SelectQuery]) orm.Loader[Q] +} + +func buildPublicreportNuisanceCountThenLoader[Q orm.Loadable]() publicreportNuisanceCountThenLoader[Q] { + type ImagesCountInterface interface { + LoadCountImages(context.Context, bob.Executor, ...bob.Mod[*dialect.SelectQuery]) error + } + + return publicreportNuisanceCountThenLoader[Q]{ + Images: countThenLoadBuilder[Q]( + "Images", + func(ctx context.Context, exec bob.Executor, retrieved ImagesCountInterface, mods ...bob.Mod[*dialect.SelectQuery]) error { + return retrieved.LoadCountImages(ctx, exec, mods...) + }, + ), + } +} + +// LoadCountImages loads the count of Images into the C struct +func (o *PublicreportNuisance) LoadCountImages(ctx context.Context, exec bob.Executor, mods ...bob.Mod[*dialect.SelectQuery]) error { + if o == nil { + return nil + } + + count, err := o.Images(mods...).Count(ctx, exec) + if err != nil { + return err + } + + o.C.Images = &count + return nil +} + +// LoadCountImages loads the count of Images for a slice +func (os PublicreportNuisanceSlice) LoadCountImages(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.LoadCountImages(ctx, exec, mods...); err != nil { + return err + } + } + + return nil +} + type publicreportNuisanceJoins[Q dialect.Joinable] struct { typ string Organization modAs[Q, organizationColumns] + Images modAs[Q, publicreportImageColumns] } func (j publicreportNuisanceJoins[Q]) aliasedAs(alias string) publicreportNuisanceJoins[Q] { @@ -977,6 +1303,28 @@ func buildPublicreportNuisanceJoins[Q dialect.Joinable](cols publicreportNuisanc )) } + return mods + }, + }, + Images: modAs[Q, publicreportImageColumns]{ + c: PublicreportImages.Columns, + f: func(to publicreportImageColumns) bob.Mod[Q] { + random := strconv.FormatInt(randInt(), 10) + mods := make(mods.QueryMods[Q], 0, 2) + + { + to := PublicreportNuisanceImages.Columns.AliasedAs(PublicreportNuisanceImages.Columns.Alias() + random) + mods = append(mods, dialect.Join[Q](typ, PublicreportNuisanceImages.Name().As(to.Alias())).On( + to.NuisanceID.EQ(cols.ID), + )) + } + { + cols := PublicreportNuisanceImages.Columns.AliasedAs(PublicreportNuisanceImages.Columns.Alias() + random) + mods = append(mods, dialect.Join[Q](typ, PublicreportImages.Name().As(to.Alias())).On( + to.ID.EQ(cols.ImageID), + )) + } + return mods }, }, diff --git a/db/models/publicreport.nuisance_image.bob.go b/db/models/publicreport.nuisance_image.bob.go new file mode 100644 index 00000000..5464a396 --- /dev/null +++ b/db/models/publicreport.nuisance_image.bob.go @@ -0,0 +1,766 @@ +// 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" + + "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" + "github.com/aarondl/opt/omit" +) + +// PublicreportNuisanceImage is an object representing the database table. +type PublicreportNuisanceImage struct { + ImageID int32 `db:"image_id,pk" ` + NuisanceID int32 `db:"nuisance_id,pk" ` + + R publicreportNuisanceImageR `db:"-" ` +} + +// PublicreportNuisanceImageSlice is an alias for a slice of pointers to PublicreportNuisanceImage. +// This should almost always be used instead of []*PublicreportNuisanceImage. +type PublicreportNuisanceImageSlice []*PublicreportNuisanceImage + +// PublicreportNuisanceImages contains methods to work with the nuisance_image table +var PublicreportNuisanceImages = psql.NewTablex[*PublicreportNuisanceImage, PublicreportNuisanceImageSlice, *PublicreportNuisanceImageSetter]("publicreport", "nuisance_image", buildPublicreportNuisanceImageColumns("publicreport.nuisance_image")) + +// PublicreportNuisanceImagesQuery is a query on the nuisance_image table +type PublicreportNuisanceImagesQuery = *psql.ViewQuery[*PublicreportNuisanceImage, PublicreportNuisanceImageSlice] + +// publicreportNuisanceImageR is where relationships are stored. +type publicreportNuisanceImageR struct { + Image *PublicreportImage // publicreport.nuisance_image.nuisance_image_image_id_fkey + Nuisance *PublicreportNuisance // publicreport.nuisance_image.nuisance_image_nuisance_id_fkey +} + +func buildPublicreportNuisanceImageColumns(alias string) publicreportNuisanceImageColumns { + return publicreportNuisanceImageColumns{ + ColumnsExpr: expr.NewColumnsExpr( + "image_id", "nuisance_id", + ).WithParent("publicreport.nuisance_image"), + tableAlias: alias, + ImageID: psql.Quote(alias, "image_id"), + NuisanceID: psql.Quote(alias, "nuisance_id"), + } +} + +type publicreportNuisanceImageColumns struct { + expr.ColumnsExpr + tableAlias string + ImageID psql.Expression + NuisanceID psql.Expression +} + +func (c publicreportNuisanceImageColumns) Alias() string { + return c.tableAlias +} + +func (publicreportNuisanceImageColumns) AliasedAs(alias string) publicreportNuisanceImageColumns { + return buildPublicreportNuisanceImageColumns(alias) +} + +// PublicreportNuisanceImageSetter is used for insert/upsert/update operations +// All values are optional, and do not have to be set +// Generated columns are not included +type PublicreportNuisanceImageSetter struct { + ImageID omit.Val[int32] `db:"image_id,pk" ` + NuisanceID omit.Val[int32] `db:"nuisance_id,pk" ` +} + +func (s PublicreportNuisanceImageSetter) SetColumns() []string { + vals := make([]string, 0, 2) + if s.ImageID.IsValue() { + vals = append(vals, "image_id") + } + if s.NuisanceID.IsValue() { + vals = append(vals, "nuisance_id") + } + return vals +} + +func (s PublicreportNuisanceImageSetter) Overwrite(t *PublicreportNuisanceImage) { + if s.ImageID.IsValue() { + t.ImageID = s.ImageID.MustGet() + } + if s.NuisanceID.IsValue() { + t.NuisanceID = s.NuisanceID.MustGet() + } +} + +func (s *PublicreportNuisanceImageSetter) Apply(q *dialect.InsertQuery) { + q.AppendHooks(func(ctx context.Context, exec bob.Executor) (context.Context, error) { + return PublicreportNuisanceImages.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, 2) + if s.ImageID.IsValue() { + vals[0] = psql.Arg(s.ImageID.MustGet()) + } else { + vals[0] = psql.Raw("DEFAULT") + } + + if s.NuisanceID.IsValue() { + vals[1] = psql.Arg(s.NuisanceID.MustGet()) + } else { + vals[1] = psql.Raw("DEFAULT") + } + + return bob.ExpressSlice(ctx, w, d, start, vals, "", ", ", "") + })) +} + +func (s PublicreportNuisanceImageSetter) UpdateMod() bob.Mod[*dialect.UpdateQuery] { + return um.Set(s.Expressions()...) +} + +func (s PublicreportNuisanceImageSetter) Expressions(prefix ...string) []bob.Expression { + exprs := make([]bob.Expression, 0, 2) + + if s.ImageID.IsValue() { + exprs = append(exprs, expr.Join{Sep: " = ", Exprs: []bob.Expression{ + psql.Quote(append(prefix, "image_id")...), + psql.Arg(s.ImageID), + }}) + } + + if s.NuisanceID.IsValue() { + exprs = append(exprs, expr.Join{Sep: " = ", Exprs: []bob.Expression{ + psql.Quote(append(prefix, "nuisance_id")...), + psql.Arg(s.NuisanceID), + }}) + } + + return exprs +} + +// FindPublicreportNuisanceImage retrieves a single record by primary key +// If cols is empty Find will return all columns. +func FindPublicreportNuisanceImage(ctx context.Context, exec bob.Executor, ImageIDPK int32, NuisanceIDPK int32, cols ...string) (*PublicreportNuisanceImage, error) { + if len(cols) == 0 { + return PublicreportNuisanceImages.Query( + sm.Where(PublicreportNuisanceImages.Columns.ImageID.EQ(psql.Arg(ImageIDPK))), + sm.Where(PublicreportNuisanceImages.Columns.NuisanceID.EQ(psql.Arg(NuisanceIDPK))), + ).One(ctx, exec) + } + + return PublicreportNuisanceImages.Query( + sm.Where(PublicreportNuisanceImages.Columns.ImageID.EQ(psql.Arg(ImageIDPK))), + sm.Where(PublicreportNuisanceImages.Columns.NuisanceID.EQ(psql.Arg(NuisanceIDPK))), + sm.Columns(PublicreportNuisanceImages.Columns.Only(cols...)), + ).One(ctx, exec) +} + +// PublicreportNuisanceImageExists checks the presence of a single record by primary key +func PublicreportNuisanceImageExists(ctx context.Context, exec bob.Executor, ImageIDPK int32, NuisanceIDPK int32) (bool, error) { + return PublicreportNuisanceImages.Query( + sm.Where(PublicreportNuisanceImages.Columns.ImageID.EQ(psql.Arg(ImageIDPK))), + sm.Where(PublicreportNuisanceImages.Columns.NuisanceID.EQ(psql.Arg(NuisanceIDPK))), + ).Exists(ctx, exec) +} + +// AfterQueryHook is called after PublicreportNuisanceImage is retrieved from the database +func (o *PublicreportNuisanceImage) AfterQueryHook(ctx context.Context, exec bob.Executor, queryType bob.QueryType) error { + var err error + + switch queryType { + case bob.QueryTypeSelect: + ctx, err = PublicreportNuisanceImages.AfterSelectHooks.RunHooks(ctx, exec, PublicreportNuisanceImageSlice{o}) + case bob.QueryTypeInsert: + ctx, err = PublicreportNuisanceImages.AfterInsertHooks.RunHooks(ctx, exec, PublicreportNuisanceImageSlice{o}) + case bob.QueryTypeUpdate: + ctx, err = PublicreportNuisanceImages.AfterUpdateHooks.RunHooks(ctx, exec, PublicreportNuisanceImageSlice{o}) + case bob.QueryTypeDelete: + ctx, err = PublicreportNuisanceImages.AfterDeleteHooks.RunHooks(ctx, exec, PublicreportNuisanceImageSlice{o}) + } + + return err +} + +// primaryKeyVals returns the primary key values of the PublicreportNuisanceImage +func (o *PublicreportNuisanceImage) primaryKeyVals() bob.Expression { + return psql.ArgGroup( + o.ImageID, + o.NuisanceID, + ) +} + +func (o *PublicreportNuisanceImage) pkEQ() dialect.Expression { + return psql.Group(psql.Quote("publicreport.nuisance_image", "image_id"), psql.Quote("publicreport.nuisance_image", "nuisance_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 PublicreportNuisanceImage +func (o *PublicreportNuisanceImage) Update(ctx context.Context, exec bob.Executor, s *PublicreportNuisanceImageSetter) error { + v, err := PublicreportNuisanceImages.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 PublicreportNuisanceImage record with an executor +func (o *PublicreportNuisanceImage) Delete(ctx context.Context, exec bob.Executor) error { + _, err := PublicreportNuisanceImages.Delete(dm.Where(o.pkEQ())).Exec(ctx, exec) + return err +} + +// Reload refreshes the PublicreportNuisanceImage using the executor +func (o *PublicreportNuisanceImage) Reload(ctx context.Context, exec bob.Executor) error { + o2, err := PublicreportNuisanceImages.Query( + sm.Where(PublicreportNuisanceImages.Columns.ImageID.EQ(psql.Arg(o.ImageID))), + sm.Where(PublicreportNuisanceImages.Columns.NuisanceID.EQ(psql.Arg(o.NuisanceID))), + ).One(ctx, exec) + if err != nil { + return err + } + o2.R = o.R + *o = *o2 + + return nil +} + +// AfterQueryHook is called after PublicreportNuisanceImageSlice is retrieved from the database +func (o PublicreportNuisanceImageSlice) AfterQueryHook(ctx context.Context, exec bob.Executor, queryType bob.QueryType) error { + var err error + + switch queryType { + case bob.QueryTypeSelect: + ctx, err = PublicreportNuisanceImages.AfterSelectHooks.RunHooks(ctx, exec, o) + case bob.QueryTypeInsert: + ctx, err = PublicreportNuisanceImages.AfterInsertHooks.RunHooks(ctx, exec, o) + case bob.QueryTypeUpdate: + ctx, err = PublicreportNuisanceImages.AfterUpdateHooks.RunHooks(ctx, exec, o) + case bob.QueryTypeDelete: + ctx, err = PublicreportNuisanceImages.AfterDeleteHooks.RunHooks(ctx, exec, o) + } + + return err +} + +func (o PublicreportNuisanceImageSlice) pkIN() dialect.Expression { + if len(o) == 0 { + return psql.Raw("NULL") + } + + return psql.Group(psql.Quote("publicreport.nuisance_image", "image_id"), psql.Quote("publicreport.nuisance_image", "nuisance_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 PublicreportNuisanceImageSlice) copyMatchingRows(from ...*PublicreportNuisanceImage) { + for i, old := range o { + for _, new := range from { + if new.ImageID != old.ImageID { + continue + } + if new.NuisanceID != old.NuisanceID { + continue + } + new.R = old.R + o[i] = new + break + } + } +} + +// UpdateMod modifies an update query with "WHERE primary_key IN (o...)" +func (o PublicreportNuisanceImageSlice) 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 PublicreportNuisanceImages.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 *PublicreportNuisanceImage: + o.copyMatchingRows(retrieved) + case []*PublicreportNuisanceImage: + o.copyMatchingRows(retrieved...) + case PublicreportNuisanceImageSlice: + o.copyMatchingRows(retrieved...) + default: + // If the retrieved value is not a PublicreportNuisanceImage or a slice of PublicreportNuisanceImage + // then run the AfterUpdateHooks on the slice + _, err = PublicreportNuisanceImages.AfterUpdateHooks.RunHooks(ctx, exec, o) + } + + return err + })) + + q.AppendWhere(o.pkIN()) + }) +} + +// DeleteMod modifies an delete query with "WHERE primary_key IN (o...)" +func (o PublicreportNuisanceImageSlice) 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 PublicreportNuisanceImages.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 *PublicreportNuisanceImage: + o.copyMatchingRows(retrieved) + case []*PublicreportNuisanceImage: + o.copyMatchingRows(retrieved...) + case PublicreportNuisanceImageSlice: + o.copyMatchingRows(retrieved...) + default: + // If the retrieved value is not a PublicreportNuisanceImage or a slice of PublicreportNuisanceImage + // then run the AfterDeleteHooks on the slice + _, err = PublicreportNuisanceImages.AfterDeleteHooks.RunHooks(ctx, exec, o) + } + + return err + })) + + q.AppendWhere(o.pkIN()) + }) +} + +func (o PublicreportNuisanceImageSlice) UpdateAll(ctx context.Context, exec bob.Executor, vals PublicreportNuisanceImageSetter) error { + if len(o) == 0 { + return nil + } + + _, err := PublicreportNuisanceImages.Update(vals.UpdateMod(), o.UpdateMod()).All(ctx, exec) + return err +} + +func (o PublicreportNuisanceImageSlice) DeleteAll(ctx context.Context, exec bob.Executor) error { + if len(o) == 0 { + return nil + } + + _, err := PublicreportNuisanceImages.Delete(o.DeleteMod()).Exec(ctx, exec) + return err +} + +func (o PublicreportNuisanceImageSlice) ReloadAll(ctx context.Context, exec bob.Executor) error { + if len(o) == 0 { + return nil + } + + o2, err := PublicreportNuisanceImages.Query(sm.Where(o.pkIN())).All(ctx, exec) + if err != nil { + return err + } + + o.copyMatchingRows(o2...) + + return nil +} + +// Image starts a query for related objects on publicreport.image +func (o *PublicreportNuisanceImage) Image(mods ...bob.Mod[*dialect.SelectQuery]) PublicreportImagesQuery { + return PublicreportImages.Query(append(mods, + sm.Where(PublicreportImages.Columns.ID.EQ(psql.Arg(o.ImageID))), + )...) +} + +func (os PublicreportNuisanceImageSlice) Image(mods ...bob.Mod[*dialect.SelectQuery]) PublicreportImagesQuery { + pkImageID := make(pgtypes.Array[int32], 0, len(os)) + for _, o := range os { + if o == nil { + continue + } + pkImageID = append(pkImageID, o.ImageID) + } + PKArgExpr := psql.Select(sm.Columns( + psql.F("unnest", psql.Cast(psql.Arg(pkImageID), "integer[]")), + )) + + return PublicreportImages.Query(append(mods, + sm.Where(psql.Group(PublicreportImages.Columns.ID).OP("IN", PKArgExpr)), + )...) +} + +// Nuisance starts a query for related objects on publicreport.nuisance +func (o *PublicreportNuisanceImage) Nuisance(mods ...bob.Mod[*dialect.SelectQuery]) PublicreportNuisancesQuery { + return PublicreportNuisances.Query(append(mods, + sm.Where(PublicreportNuisances.Columns.ID.EQ(psql.Arg(o.NuisanceID))), + )...) +} + +func (os PublicreportNuisanceImageSlice) Nuisance(mods ...bob.Mod[*dialect.SelectQuery]) PublicreportNuisancesQuery { + pkNuisanceID := make(pgtypes.Array[int32], 0, len(os)) + for _, o := range os { + if o == nil { + continue + } + pkNuisanceID = append(pkNuisanceID, o.NuisanceID) + } + PKArgExpr := psql.Select(sm.Columns( + psql.F("unnest", psql.Cast(psql.Arg(pkNuisanceID), "integer[]")), + )) + + return PublicreportNuisances.Query(append(mods, + sm.Where(psql.Group(PublicreportNuisances.Columns.ID).OP("IN", PKArgExpr)), + )...) +} + +func attachPublicreportNuisanceImageImage0(ctx context.Context, exec bob.Executor, count int, publicreportNuisanceImage0 *PublicreportNuisanceImage, publicreportImage1 *PublicreportImage) (*PublicreportNuisanceImage, error) { + setter := &PublicreportNuisanceImageSetter{ + ImageID: omit.From(publicreportImage1.ID), + } + + err := publicreportNuisanceImage0.Update(ctx, exec, setter) + if err != nil { + return nil, fmt.Errorf("attachPublicreportNuisanceImageImage0: %w", err) + } + + return publicreportNuisanceImage0, nil +} + +func (publicreportNuisanceImage0 *PublicreportNuisanceImage) InsertImage(ctx context.Context, exec bob.Executor, related *PublicreportImageSetter) error { + var err error + + publicreportImage1, err := PublicreportImages.Insert(related).One(ctx, exec) + if err != nil { + return fmt.Errorf("inserting related objects: %w", err) + } + + _, err = attachPublicreportNuisanceImageImage0(ctx, exec, 1, publicreportNuisanceImage0, publicreportImage1) + if err != nil { + return err + } + + publicreportNuisanceImage0.R.Image = publicreportImage1 + + return nil +} + +func (publicreportNuisanceImage0 *PublicreportNuisanceImage) AttachImage(ctx context.Context, exec bob.Executor, publicreportImage1 *PublicreportImage) error { + var err error + + _, err = attachPublicreportNuisanceImageImage0(ctx, exec, 1, publicreportNuisanceImage0, publicreportImage1) + if err != nil { + return err + } + + publicreportNuisanceImage0.R.Image = publicreportImage1 + + return nil +} + +func attachPublicreportNuisanceImageNuisance0(ctx context.Context, exec bob.Executor, count int, publicreportNuisanceImage0 *PublicreportNuisanceImage, publicreportNuisance1 *PublicreportNuisance) (*PublicreportNuisanceImage, error) { + setter := &PublicreportNuisanceImageSetter{ + NuisanceID: omit.From(publicreportNuisance1.ID), + } + + err := publicreportNuisanceImage0.Update(ctx, exec, setter) + if err != nil { + return nil, fmt.Errorf("attachPublicreportNuisanceImageNuisance0: %w", err) + } + + return publicreportNuisanceImage0, nil +} + +func (publicreportNuisanceImage0 *PublicreportNuisanceImage) InsertNuisance(ctx context.Context, exec bob.Executor, related *PublicreportNuisanceSetter) error { + var err error + + publicreportNuisance1, err := PublicreportNuisances.Insert(related).One(ctx, exec) + if err != nil { + return fmt.Errorf("inserting related objects: %w", err) + } + + _, err = attachPublicreportNuisanceImageNuisance0(ctx, exec, 1, publicreportNuisanceImage0, publicreportNuisance1) + if err != nil { + return err + } + + publicreportNuisanceImage0.R.Nuisance = publicreportNuisance1 + + return nil +} + +func (publicreportNuisanceImage0 *PublicreportNuisanceImage) AttachNuisance(ctx context.Context, exec bob.Executor, publicreportNuisance1 *PublicreportNuisance) error { + var err error + + _, err = attachPublicreportNuisanceImageNuisance0(ctx, exec, 1, publicreportNuisanceImage0, publicreportNuisance1) + if err != nil { + return err + } + + publicreportNuisanceImage0.R.Nuisance = publicreportNuisance1 + + return nil +} + +type publicreportNuisanceImageWhere[Q psql.Filterable] struct { + ImageID psql.WhereMod[Q, int32] + NuisanceID psql.WhereMod[Q, int32] +} + +func (publicreportNuisanceImageWhere[Q]) AliasedAs(alias string) publicreportNuisanceImageWhere[Q] { + return buildPublicreportNuisanceImageWhere[Q](buildPublicreportNuisanceImageColumns(alias)) +} + +func buildPublicreportNuisanceImageWhere[Q psql.Filterable](cols publicreportNuisanceImageColumns) publicreportNuisanceImageWhere[Q] { + return publicreportNuisanceImageWhere[Q]{ + ImageID: psql.Where[Q, int32](cols.ImageID), + NuisanceID: psql.Where[Q, int32](cols.NuisanceID), + } +} + +func (o *PublicreportNuisanceImage) Preload(name string, retrieved any) error { + if o == nil { + return nil + } + + switch name { + case "Image": + rel, ok := retrieved.(*PublicreportImage) + if !ok { + return fmt.Errorf("publicreportNuisanceImage cannot load %T as %q", retrieved, name) + } + + o.R.Image = rel + + return nil + case "Nuisance": + rel, ok := retrieved.(*PublicreportNuisance) + if !ok { + return fmt.Errorf("publicreportNuisanceImage cannot load %T as %q", retrieved, name) + } + + o.R.Nuisance = rel + + return nil + default: + return fmt.Errorf("publicreportNuisanceImage has no relationship %q", name) + } +} + +type publicreportNuisanceImagePreloader struct { + Image func(...psql.PreloadOption) psql.Preloader + Nuisance func(...psql.PreloadOption) psql.Preloader +} + +func buildPublicreportNuisanceImagePreloader() publicreportNuisanceImagePreloader { + return publicreportNuisanceImagePreloader{ + Image: func(opts ...psql.PreloadOption) psql.Preloader { + return psql.Preload[*PublicreportImage, PublicreportImageSlice](psql.PreloadRel{ + Name: "Image", + Sides: []psql.PreloadSide{ + { + From: PublicreportNuisanceImages, + To: PublicreportImages, + FromColumns: []string{"image_id"}, + ToColumns: []string{"id"}, + }, + }, + }, PublicreportImages.Columns.Names(), opts...) + }, + Nuisance: func(opts ...psql.PreloadOption) psql.Preloader { + return psql.Preload[*PublicreportNuisance, PublicreportNuisanceSlice](psql.PreloadRel{ + Name: "Nuisance", + Sides: []psql.PreloadSide{ + { + From: PublicreportNuisanceImages, + To: PublicreportNuisances, + FromColumns: []string{"nuisance_id"}, + ToColumns: []string{"id"}, + }, + }, + }, PublicreportNuisances.Columns.Names(), opts...) + }, + } +} + +type publicreportNuisanceImageThenLoader[Q orm.Loadable] struct { + Image func(...bob.Mod[*dialect.SelectQuery]) orm.Loader[Q] + Nuisance func(...bob.Mod[*dialect.SelectQuery]) orm.Loader[Q] +} + +func buildPublicreportNuisanceImageThenLoader[Q orm.Loadable]() publicreportNuisanceImageThenLoader[Q] { + type ImageLoadInterface interface { + LoadImage(context.Context, bob.Executor, ...bob.Mod[*dialect.SelectQuery]) error + } + type NuisanceLoadInterface interface { + LoadNuisance(context.Context, bob.Executor, ...bob.Mod[*dialect.SelectQuery]) error + } + + return publicreportNuisanceImageThenLoader[Q]{ + Image: thenLoadBuilder[Q]( + "Image", + func(ctx context.Context, exec bob.Executor, retrieved ImageLoadInterface, mods ...bob.Mod[*dialect.SelectQuery]) error { + return retrieved.LoadImage(ctx, exec, mods...) + }, + ), + Nuisance: thenLoadBuilder[Q]( + "Nuisance", + func(ctx context.Context, exec bob.Executor, retrieved NuisanceLoadInterface, mods ...bob.Mod[*dialect.SelectQuery]) error { + return retrieved.LoadNuisance(ctx, exec, mods...) + }, + ), + } +} + +// LoadImage loads the publicreportNuisanceImage's Image into the .R struct +func (o *PublicreportNuisanceImage) LoadImage(ctx context.Context, exec bob.Executor, mods ...bob.Mod[*dialect.SelectQuery]) error { + if o == nil { + return nil + } + + // Reset the relationship + o.R.Image = nil + + related, err := o.Image(mods...).One(ctx, exec) + if err != nil { + return err + } + + o.R.Image = related + return nil +} + +// LoadImage loads the publicreportNuisanceImage's Image into the .R struct +func (os PublicreportNuisanceImageSlice) LoadImage(ctx context.Context, exec bob.Executor, mods ...bob.Mod[*dialect.SelectQuery]) error { + if len(os) == 0 { + return nil + } + + publicreportImages, err := os.Image(mods...).All(ctx, exec) + if err != nil { + return err + } + + for _, o := range os { + if o == nil { + continue + } + + for _, rel := range publicreportImages { + + if !(o.ImageID == rel.ID) { + continue + } + + o.R.Image = rel + break + } + } + + return nil +} + +// LoadNuisance loads the publicreportNuisanceImage's Nuisance into the .R struct +func (o *PublicreportNuisanceImage) LoadNuisance(ctx context.Context, exec bob.Executor, mods ...bob.Mod[*dialect.SelectQuery]) error { + if o == nil { + return nil + } + + // Reset the relationship + o.R.Nuisance = nil + + related, err := o.Nuisance(mods...).One(ctx, exec) + if err != nil { + return err + } + + o.R.Nuisance = related + return nil +} + +// LoadNuisance loads the publicreportNuisanceImage's Nuisance into the .R struct +func (os PublicreportNuisanceImageSlice) LoadNuisance(ctx context.Context, exec bob.Executor, mods ...bob.Mod[*dialect.SelectQuery]) error { + if len(os) == 0 { + return nil + } + + publicreportNuisances, err := os.Nuisance(mods...).All(ctx, exec) + if err != nil { + return err + } + + for _, o := range os { + if o == nil { + continue + } + + for _, rel := range publicreportNuisances { + + if !(o.NuisanceID == rel.ID) { + continue + } + + o.R.Nuisance = rel + break + } + } + + return nil +} + +type publicreportNuisanceImageJoins[Q dialect.Joinable] struct { + typ string + Image modAs[Q, publicreportImageColumns] + Nuisance modAs[Q, publicreportNuisanceColumns] +} + +func (j publicreportNuisanceImageJoins[Q]) aliasedAs(alias string) publicreportNuisanceImageJoins[Q] { + return buildPublicreportNuisanceImageJoins[Q](buildPublicreportNuisanceImageColumns(alias), j.typ) +} + +func buildPublicreportNuisanceImageJoins[Q dialect.Joinable](cols publicreportNuisanceImageColumns, typ string) publicreportNuisanceImageJoins[Q] { + return publicreportNuisanceImageJoins[Q]{ + typ: typ, + Image: modAs[Q, publicreportImageColumns]{ + c: PublicreportImages.Columns, + f: func(to publicreportImageColumns) bob.Mod[Q] { + mods := make(mods.QueryMods[Q], 0, 1) + + { + mods = append(mods, dialect.Join[Q](typ, PublicreportImages.Name().As(to.Alias())).On( + to.ID.EQ(cols.ImageID), + )) + } + + return mods + }, + }, + Nuisance: modAs[Q, publicreportNuisanceColumns]{ + c: PublicreportNuisances.Columns, + f: func(to publicreportNuisanceColumns) bob.Mod[Q] { + mods := make(mods.QueryMods[Q], 0, 1) + + { + mods = append(mods, dialect.Join[Q](typ, PublicreportNuisances.Name().As(to.Alias())).On( + to.ID.EQ(cols.NuisanceID), + )) + } + + return mods + }, + }, + } +} diff --git a/rmo/nuisance.go b/rmo/nuisance.go index a0e6b422..6706ed69 100644 --- a/rmo/nuisance.go +++ b/rmo/nuisance.go @@ -3,12 +3,17 @@ package rmo import ( "fmt" "net/http" + "strconv" "time" + "github.com/Gleipnir-Technology/bob" + "github.com/Gleipnir-Technology/bob/dialect/psql" + "github.com/Gleipnir-Technology/bob/dialect/psql/um" "github.com/Gleipnir-Technology/nidus-sync/config" "github.com/Gleipnir-Technology/nidus-sync/db" "github.com/Gleipnir-Technology/nidus-sync/db/enums" "github.com/Gleipnir-Technology/nidus-sync/db/models" + "github.com/Gleipnir-Technology/nidus-sync/h3utils" "github.com/Gleipnir-Technology/nidus-sync/html" "github.com/Gleipnir-Technology/nidus-sync/platform/report" "github.com/aarondl/opt/omit" @@ -56,12 +61,15 @@ func getSubmitComplete(w http.ResponseWriter, r *http.Request) { ) } func postNuisance(w http.ResponseWriter, r *http.Request) { - err := r.ParseForm() + ctx := r.Context() + err := r.ParseMultipartForm(32 << 10) // 32 MB buffer if err != nil { respondError(w, "Failed to parse form", err, http.StatusBadRequest) return } address := r.PostFormValue("address") + lat := r.FormValue("latitude") + lng := r.FormValue("longitude") source_stagnant := boolFromForm(r, "source-stagnant") source_container := boolFromForm(r, "source-container") source_gutters := boolFromForm(r, "source-gutters") @@ -85,34 +93,99 @@ func postNuisance(w http.ResponseWriter, r *http.Request) { source_description := r.PostFormValue("source-description") additional_info := r.PostFormValue("additional-info") + latitude, err := strconv.ParseFloat(lat, 64) + if err != nil { + respondError(w, "Failed to create parse latitude", err, http.StatusBadRequest) + return + } + longitude, err := strconv.ParseFloat(lng, 64) + if err != nil { + respondError(w, "Failed to create parse longitude", err, http.StatusBadRequest) + return + } public_id, err := report.GenerateReportID() if err != nil { respondError(w, "Failed to create quick report public ID", err, http.StatusInternalServerError) return } + txn, err := db.PGInstance.BobDB.BeginTx(ctx, nil) + if err != nil { + respondError(w, "Failed to create transaction", err, http.StatusInternalServerError) + return + } + defer txn.Rollback(ctx) + + uploads, err := extractImageUploads(r) + log.Info().Int("len", len(uploads)).Msg("extracted uploads") + if err != nil { + respondError(w, "Failed to extract image uploads", err, http.StatusInternalServerError) + return + } + images, err := saveImageUploads(ctx, txn, uploads) + if err != nil { + respondError(w, "Failed to save image uploads", err, http.StatusInternalServerError) + return + } + organization_id, err := matchDistrict(ctx, longitude, latitude, uploads) + if err != nil { + log.Warn().Err(err).Msg("Failed to match district") + } + c, err := h3utils.GetCell(longitude, latitude, 15) + if err != nil { + respondError(w, "Failedt o get h3 cell", err, http.StatusInternalServerError) + } + setter := models.PublicreportNuisanceSetter{ - AdditionalInfo: omit.From(additional_info), - Address: omit.From(address), - Created: omit.From(time.Now()), - Duration: omit.From(duration), + AdditionalInfo: omit.From(additional_info), + Address: omit.From(address), + Created: omit.From(time.Now()), + Duration: omit.From(duration), + H3cell: omitnull.From(c.String()), + //Location: omitnull.From(fmt.Sprintf("ST_GeometryFromText(Point(%s %s))", longitude, latitude)), Location: omitnull.FromPtr[string](nil), + OrganizationID: omitnull.FromPtr(organization_id), PublicID: omit.From(public_id), + ReporterEmail: omitnull.FromPtr[string](nil), + ReporterName: omitnull.FromPtr[string](nil), + ReporterPhone: omitnull.FromPtr[string](nil), SourceContainer: omit.From(source_container), SourceDescription: omit.From(source_description), SourceGutter: omit.From(source_gutters), SourceLocation: omit.From(source_location), SourceStagnant: omit.From(source_stagnant), Status: omit.From(enums.PublicreportReportstatustypeReported), - ReporterEmail: omitnull.FromPtr[string](nil), - ReporterName: omitnull.FromPtr[string](nil), - ReporterPhone: omitnull.FromPtr[string](nil), } - nuisance, err := models.PublicreportNuisances.Insert(&setter).One(r.Context(), db.PGInstance.BobDB) + nuisance, err := models.PublicreportNuisances.Insert(&setter).One(ctx, txn) if err != nil { respondError(w, "Failed to create database record", err, http.StatusInternalServerError) return } + _, err = psql.Update( + um.Table("publicreport.nuisance"), + um.SetCol("location").To(fmt.Sprintf("ST_GeometryFromText('Point(%f %f)')", longitude, latitude)), + um.Where(psql.Quote("id").EQ(psql.Arg(nuisance.ID))), + ).Exec(ctx, txn) + if err != nil { + respondError(w, "Failed to insert publicreport", err, http.StatusInternalServerError) + return + } log.Info().Str("public_id", public_id).Int32("id", nuisance.ID).Msg("Created nuisance report") + if len(images) > 0 { + setters := make([]*models.PublicreportNuisanceImageSetter, 0) + for _, image := range images { + setters = append(setters, &models.PublicreportNuisanceImageSetter{ + ImageID: omit.From(int32(image.ID)), + NuisanceID: omit.From(int32(nuisance.ID)), + }) + } + _, err = models.PublicreportNuisanceImages.Insert(bob.ToMods(setters...)).Exec(ctx, txn) + if err != nil { + respondError(w, "Failed to save reference to images", err, http.StatusInternalServerError) + return + } + log.Info().Int("len", len(images)).Msg("saved uploads") + } + txn.Commit(ctx) http.Redirect(w, r, fmt.Sprintf("/submit-complete?report=%s", public_id), http.StatusFound) } diff --git a/rmo/quick.go b/rmo/quick.go index becae56e..4eb0eede 100644 --- a/rmo/quick.go +++ b/rmo/quick.go @@ -176,6 +176,9 @@ func postQuick(w http.ResponseWriter, r *http.Request) { log.Info().Int("len", len(images)).Msg("saved uploads") c, err := h3utils.GetCell(longitude, latitude, 15) + if err != nil { + respondError(w, "Failedt o get h3 cell", err, http.StatusInternalServerError) + } setter := models.PublicreportQuickSetter{ Address: omit.From(""), Created: omit.From(time.Now()),