From 01ed2d60866c605bb75dfb1c787af278ad93a9d8 Mon Sep 17 00:00:00 2001 From: Eli Ribble Date: Fri, 9 Jan 2026 19:43:19 +0000 Subject: [PATCH] Finish green pool report submission Also start the pattern of breaking out pool pages together in their own file. I think its easier to read this way. --- db/dberrors/publicreport.pool.bob.go | 26 + db/dberrors/publicreport.pool_photo.bob.go | 17 + db/dbinfo/publicreport.pool.bob.go | 402 ++++ db/dbinfo/publicreport.pool_photo.bob.go | 147 ++ db/enums/enums.bob.go | 85 + db/factory/bobfactory_context.bob.go | 8 + db/factory/bobfactory_main.bob.go | 108 ++ db/factory/publicreport.pool.bob.go | 1613 +++++++++++++++++ db/factory/publicreport.pool_photo.bob.go | 498 +++++ ...eport.sql => 00024_publicreport_quick.sql} | 0 ...ce.sql => 00025_publicreport_nuisance.sql} | 0 db/migrations/00026_publicreport_pool.sql | 53 + db/models/bob_joins.bob.go | 4 + db/models/bob_loaders.bob.go | 8 + db/models/bob_where.bob.go | 6 + db/models/publicreport.pool.bob.go | 1295 +++++++++++++ db/models/publicreport.pool_photo.bob.go | 678 +++++++ h3utils/h3.go | 41 + public-report/endpoint.go | 199 +- public-report/geospatial.go | 69 + public-report/page.go | 12 +- public-report/photo-upload.go | 64 + public-report/pool.go | 165 ++ public-report/quick.go | 117 ++ public-report/routes.go | 28 + .../component/location-geocode-header.html | 45 +- .../template/component/location-geocode.html | 13 +- .../template/component/map-header.html | 142 -- .../template/component/photo-upload.html | 1 - .../template/pool-submit-complete.html | 115 ++ public-report/template/pool.html | 341 +++- 31 files changed, 5925 insertions(+), 375 deletions(-) create mode 100644 db/dberrors/publicreport.pool.bob.go create mode 100644 db/dberrors/publicreport.pool_photo.bob.go create mode 100644 db/dbinfo/publicreport.pool.bob.go create mode 100644 db/dbinfo/publicreport.pool_photo.bob.go create mode 100644 db/factory/publicreport.pool.bob.go create mode 100644 db/factory/publicreport.pool_photo.bob.go rename db/migrations/{00024_public_report.sql => 00024_publicreport_quick.sql} (100%) rename db/migrations/{00025_public_nuisance.sql => 00025_publicreport_nuisance.sql} (100%) create mode 100644 db/migrations/00026_publicreport_pool.sql create mode 100644 db/models/publicreport.pool.bob.go create mode 100644 db/models/publicreport.pool_photo.bob.go create mode 100644 public-report/geospatial.go create mode 100644 public-report/photo-upload.go create mode 100644 public-report/pool.go create mode 100644 public-report/quick.go create mode 100644 public-report/routes.go create mode 100644 public-report/template/pool-submit-complete.html diff --git a/db/dberrors/publicreport.pool.bob.go b/db/dberrors/publicreport.pool.bob.go new file mode 100644 index 00000000..d7ab3834 --- /dev/null +++ b/db/dberrors/publicreport.pool.bob.go @@ -0,0 +1,26 @@ +// Code generated by BobGen psql v0.0.4-0.20260105020634-53e08d840e47+dirty. DO NOT EDIT. +// This file is meant to be re-generated in place and/or deleted at any time. + +package dberrors + +var PublicreportPoolErrors = &publicreportPoolErrors{ + ErrUniquePoolPkey: &UniqueConstraintError{ + schema: "publicreport", + table: "pool", + columns: []string{"id"}, + s: "pool_pkey", + }, + + ErrUniquePoolPublicIdKey: &UniqueConstraintError{ + schema: "publicreport", + table: "pool", + columns: []string{"public_id"}, + s: "pool_public_id_key", + }, +} + +type publicreportPoolErrors struct { + ErrUniquePoolPkey *UniqueConstraintError + + ErrUniquePoolPublicIdKey *UniqueConstraintError +} diff --git a/db/dberrors/publicreport.pool_photo.bob.go b/db/dberrors/publicreport.pool_photo.bob.go new file mode 100644 index 00000000..2bfed48d --- /dev/null +++ b/db/dberrors/publicreport.pool_photo.bob.go @@ -0,0 +1,17 @@ +// Code generated by BobGen psql v0.0.4-0.20260105020634-53e08d840e47+dirty. DO NOT EDIT. +// This file is meant to be re-generated in place and/or deleted at any time. + +package dberrors + +var PublicreportPoolPhotoErrors = &publicreportPoolPhotoErrors{ + ErrUniquePoolPhotoPkey: &UniqueConstraintError{ + schema: "publicreport", + table: "pool_photo", + columns: []string{"id"}, + s: "pool_photo_pkey", + }, +} + +type publicreportPoolPhotoErrors struct { + ErrUniquePoolPhotoPkey *UniqueConstraintError +} diff --git a/db/dbinfo/publicreport.pool.bob.go b/db/dbinfo/publicreport.pool.bob.go new file mode 100644 index 00000000..a344e623 --- /dev/null +++ b/db/dbinfo/publicreport.pool.bob.go @@ -0,0 +1,402 @@ +// Code generated by BobGen psql v0.0.4-0.20260105020634-53e08d840e47+dirty. 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 PublicreportPools = Table[ + publicreportPoolColumns, + publicreportPoolIndexes, + publicreportPoolForeignKeys, + publicreportPoolUniques, + publicreportPoolChecks, +]{ + Schema: "publicreport", + Name: "pool", + Columns: publicreportPoolColumns{ + ID: column{ + Name: "id", + DBType: "integer", + Default: "nextval('publicreport.pool_id_seq'::regclass)", + Comment: "", + Nullable: false, + Generated: false, + AutoIncr: false, + }, + AccessComments: column{ + Name: "access_comments", + DBType: "text", + Default: "", + Comment: "", + Nullable: false, + Generated: false, + AutoIncr: false, + }, + AccessGate: column{ + Name: "access_gate", + DBType: "boolean", + Default: "", + Comment: "", + Nullable: false, + Generated: false, + AutoIncr: false, + }, + AccessFence: column{ + Name: "access_fence", + DBType: "boolean", + Default: "", + Comment: "", + Nullable: false, + Generated: false, + AutoIncr: false, + }, + AccessLocked: column{ + Name: "access_locked", + DBType: "boolean", + Default: "", + Comment: "", + Nullable: false, + Generated: false, + AutoIncr: false, + }, + AccessDog: column{ + Name: "access_dog", + DBType: "boolean", + Default: "", + Comment: "", + Nullable: false, + Generated: false, + AutoIncr: false, + }, + AccessOther: column{ + Name: "access_other", + DBType: "boolean", + Default: "", + Comment: "", + Nullable: false, + Generated: false, + AutoIncr: false, + }, + Address: column{ + Name: "address", + DBType: "text", + Default: "", + Comment: "", + Nullable: false, + Generated: false, + AutoIncr: false, + }, + AddressCountry: column{ + Name: "address_country", + DBType: "text", + Default: "", + Comment: "", + Nullable: false, + Generated: false, + AutoIncr: false, + }, + AddressPostCode: column{ + Name: "address_post_code", + DBType: "text", + Default: "", + Comment: "", + Nullable: false, + Generated: false, + AutoIncr: false, + }, + AddressPlace: column{ + Name: "address_place", + DBType: "text", + Default: "", + Comment: "", + Nullable: false, + Generated: false, + AutoIncr: false, + }, + AddressStreet: column{ + Name: "address_street", + DBType: "text", + Default: "", + Comment: "", + Nullable: false, + Generated: false, + AutoIncr: false, + }, + AddressRegion: column{ + Name: "address_region", + DBType: "text", + Default: "", + Comment: "", + Nullable: false, + Generated: false, + AutoIncr: false, + }, + Comments: column{ + Name: "comments", + DBType: "text", + Default: "", + Comment: "", + Nullable: false, + Generated: false, + AutoIncr: false, + }, + Created: column{ + Name: "created", + DBType: "timestamp without time zone", + Default: "", + Comment: "", + Nullable: false, + Generated: false, + AutoIncr: false, + }, + H3cell: column{ + Name: "h3cell", + DBType: "h3index", + Default: "NULL", + Comment: "", + Nullable: true, + Generated: false, + AutoIncr: false, + }, + HasAdult: column{ + Name: "has_adult", + DBType: "boolean", + Default: "", + Comment: "", + Nullable: false, + Generated: false, + AutoIncr: false, + }, + HasLarvae: column{ + Name: "has_larvae", + DBType: "boolean", + Default: "", + Comment: "", + Nullable: false, + Generated: false, + AutoIncr: false, + }, + HasPupae: column{ + Name: "has_pupae", + DBType: "boolean", + Default: "", + Comment: "", + Nullable: false, + Generated: false, + AutoIncr: false, + }, + Location: column{ + Name: "location", + DBType: "geography", + Default: "NULL", + Comment: "", + Nullable: true, + Generated: false, + AutoIncr: false, + }, + MapZoom: column{ + Name: "map_zoom", + DBType: "double precision", + Default: "", + Comment: "", + Nullable: false, + Generated: false, + AutoIncr: false, + }, + OwnerEmail: column{ + Name: "owner_email", + DBType: "text", + Default: "", + Comment: "", + Nullable: false, + Generated: false, + AutoIncr: false, + }, + OwnerName: column{ + Name: "owner_name", + DBType: "text", + Default: "", + Comment: "", + Nullable: false, + Generated: false, + AutoIncr: false, + }, + OwnerPhone: column{ + Name: "owner_phone", + DBType: "text", + Default: "", + Comment: "", + Nullable: false, + Generated: false, + AutoIncr: false, + }, + PublicID: column{ + Name: "public_id", + DBType: "text", + Default: "", + Comment: "", + Nullable: false, + Generated: false, + AutoIncr: false, + }, + ReporterEmail: column{ + Name: "reporter_email", + DBType: "text", + Default: "", + Comment: "", + Nullable: false, + Generated: false, + AutoIncr: false, + }, + ReporterName: column{ + Name: "reporter_name", + DBType: "text", + Default: "", + Comment: "", + Nullable: false, + Generated: false, + AutoIncr: false, + }, + ReporterPhone: column{ + Name: "reporter_phone", + DBType: "text", + Default: "", + Comment: "", + Nullable: false, + Generated: false, + AutoIncr: false, + }, + Subscribe: column{ + Name: "subscribe", + DBType: "boolean", + Default: "", + Comment: "", + Nullable: false, + Generated: false, + AutoIncr: false, + }, + }, + Indexes: publicreportPoolIndexes{ + PoolPkey: index{ + Type: "btree", + Name: "pool_pkey", + Columns: []indexColumn{ + { + Name: "id", + Desc: null.FromCond(false, true), + IsExpression: false, + }, + }, + Unique: true, + Comment: "", + NullsFirst: []bool{false}, + NullsDistinct: false, + Where: "", + Include: []string{}, + }, + PoolPublicIDKey: index{ + Type: "btree", + Name: "pool_public_id_key", + Columns: []indexColumn{ + { + Name: "public_id", + Desc: null.FromCond(false, true), + IsExpression: false, + }, + }, + Unique: true, + Comment: "", + NullsFirst: []bool{false}, + NullsDistinct: false, + Where: "", + Include: []string{}, + }, + }, + PrimaryKey: &constraint{ + Name: "pool_pkey", + Columns: []string{"id"}, + Comment: "", + }, + + Uniques: publicreportPoolUniques{ + PoolPublicIDKey: constraint{ + Name: "pool_public_id_key", + Columns: []string{"public_id"}, + Comment: "", + }, + }, + + Comment: "", +} + +type publicreportPoolColumns struct { + ID column + AccessComments column + AccessGate column + AccessFence column + AccessLocked column + AccessDog column + AccessOther column + Address column + AddressCountry column + AddressPostCode column + AddressPlace column + AddressStreet column + AddressRegion column + Comments column + Created column + H3cell column + HasAdult column + HasLarvae column + HasPupae column + Location column + MapZoom column + OwnerEmail column + OwnerName column + OwnerPhone column + PublicID column + ReporterEmail column + ReporterName column + ReporterPhone column + Subscribe column +} + +func (c publicreportPoolColumns) AsSlice() []column { + return []column{ + c.ID, c.AccessComments, c.AccessGate, c.AccessFence, c.AccessLocked, c.AccessDog, c.AccessOther, c.Address, c.AddressCountry, c.AddressPostCode, c.AddressPlace, c.AddressStreet, c.AddressRegion, c.Comments, c.Created, c.H3cell, c.HasAdult, c.HasLarvae, c.HasPupae, c.Location, c.MapZoom, c.OwnerEmail, c.OwnerName, c.OwnerPhone, c.PublicID, c.ReporterEmail, c.ReporterName, c.ReporterPhone, c.Subscribe, + } +} + +type publicreportPoolIndexes struct { + PoolPkey index + PoolPublicIDKey index +} + +func (i publicreportPoolIndexes) AsSlice() []index { + return []index{ + i.PoolPkey, i.PoolPublicIDKey, + } +} + +type publicreportPoolForeignKeys struct{} + +func (f publicreportPoolForeignKeys) AsSlice() []foreignKey { + return []foreignKey{} +} + +type publicreportPoolUniques struct { + PoolPublicIDKey constraint +} + +func (u publicreportPoolUniques) AsSlice() []constraint { + return []constraint{ + u.PoolPublicIDKey, + } +} + +type publicreportPoolChecks struct{} + +func (c publicreportPoolChecks) AsSlice() []check { + return []check{} +} diff --git a/db/dbinfo/publicreport.pool_photo.bob.go b/db/dbinfo/publicreport.pool_photo.bob.go new file mode 100644 index 00000000..8d22839c --- /dev/null +++ b/db/dbinfo/publicreport.pool_photo.bob.go @@ -0,0 +1,147 @@ +// Code generated by BobGen psql v0.0.4-0.20260105020634-53e08d840e47+dirty. 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 PublicreportPoolPhotos = Table[ + publicreportPoolPhotoColumns, + publicreportPoolPhotoIndexes, + publicreportPoolPhotoForeignKeys, + publicreportPoolPhotoUniques, + publicreportPoolPhotoChecks, +]{ + Schema: "publicreport", + Name: "pool_photo", + Columns: publicreportPoolPhotoColumns{ + ID: column{ + Name: "id", + DBType: "integer", + Default: "nextval('publicreport.pool_photo_id_seq'::regclass)", + Comment: "", + Nullable: false, + Generated: false, + AutoIncr: false, + }, + Size: column{ + Name: "size", + DBType: "bigint", + Default: "", + Comment: "", + Nullable: false, + Generated: false, + AutoIncr: false, + }, + Filename: column{ + Name: "filename", + DBType: "text", + Default: "", + Comment: "", + Nullable: false, + Generated: false, + AutoIncr: false, + }, + PoolID: column{ + Name: "pool_id", + DBType: "integer", + Default: "", + Comment: "", + Nullable: false, + Generated: false, + AutoIncr: false, + }, + UUID: column{ + Name: "uuid", + DBType: "uuid", + Default: "", + Comment: "", + Nullable: false, + Generated: false, + AutoIncr: false, + }, + }, + Indexes: publicreportPoolPhotoIndexes{ + PoolPhotoPkey: index{ + Type: "btree", + Name: "pool_photo_pkey", + Columns: []indexColumn{ + { + Name: "id", + Desc: null.FromCond(false, true), + IsExpression: false, + }, + }, + Unique: true, + Comment: "", + NullsFirst: []bool{false}, + NullsDistinct: false, + Where: "", + Include: []string{}, + }, + }, + PrimaryKey: &constraint{ + Name: "pool_photo_pkey", + Columns: []string{"id"}, + Comment: "", + }, + ForeignKeys: publicreportPoolPhotoForeignKeys{ + PublicreportPoolPhotoPoolPhotoPoolIDFkey: foreignKey{ + constraint: constraint{ + Name: "publicreport.pool_photo.pool_photo_pool_id_fkey", + Columns: []string{"pool_id"}, + Comment: "", + }, + ForeignTable: "publicreport.pool", + ForeignColumns: []string{"id"}, + }, + }, + + Comment: "", +} + +type publicreportPoolPhotoColumns struct { + ID column + Size column + Filename column + PoolID column + UUID column +} + +func (c publicreportPoolPhotoColumns) AsSlice() []column { + return []column{ + c.ID, c.Size, c.Filename, c.PoolID, c.UUID, + } +} + +type publicreportPoolPhotoIndexes struct { + PoolPhotoPkey index +} + +func (i publicreportPoolPhotoIndexes) AsSlice() []index { + return []index{ + i.PoolPhotoPkey, + } +} + +type publicreportPoolPhotoForeignKeys struct { + PublicreportPoolPhotoPoolPhotoPoolIDFkey foreignKey +} + +func (f publicreportPoolPhotoForeignKeys) AsSlice() []foreignKey { + return []foreignKey{ + f.PublicreportPoolPhotoPoolPhotoPoolIDFkey, + } +} + +type publicreportPoolPhotoUniques struct{} + +func (u publicreportPoolPhotoUniques) AsSlice() []constraint { + return []constraint{} +} + +type publicreportPoolPhotoChecks struct{} + +func (c publicreportPoolPhotoChecks) AsSlice() []check { + return []check{} +} diff --git a/db/enums/enums.bob.go b/db/enums/enums.bob.go index d4867742..80797315 100644 --- a/db/enums/enums.bob.go +++ b/db/enums/enums.bob.go @@ -890,3 +890,88 @@ func (e *PublicreportNuisancepreferredtimetype) Scan(value any) error { return nil } + +// Enum values for PublicreportPoolsourceduration +const ( + PublicreportPoolsourcedurationNone PublicreportPoolsourceduration = "none" + PublicreportPoolsourcedurationLessThanWeek PublicreportPoolsourceduration = "less-than-week" + PublicreportPoolsourceduration12Weeks PublicreportPoolsourceduration = "1-2-weeks" + PublicreportPoolsourceduration24Weeks PublicreportPoolsourceduration = "2-4-weeks" + PublicreportPoolsourceduration13Months PublicreportPoolsourceduration = "1-3-months" + PublicreportPoolsourcedurationMoreThan3Months PublicreportPoolsourceduration = "more-than-3-months" +) + +func AllPublicreportPoolsourceduration() []PublicreportPoolsourceduration { + return []PublicreportPoolsourceduration{ + PublicreportPoolsourcedurationNone, + PublicreportPoolsourcedurationLessThanWeek, + PublicreportPoolsourceduration12Weeks, + PublicreportPoolsourceduration24Weeks, + PublicreportPoolsourceduration13Months, + PublicreportPoolsourcedurationMoreThan3Months, + } +} + +type PublicreportPoolsourceduration string + +func (e PublicreportPoolsourceduration) String() string { + return string(e) +} + +func (e PublicreportPoolsourceduration) Valid() bool { + switch e { + case PublicreportPoolsourcedurationNone, + PublicreportPoolsourcedurationLessThanWeek, + PublicreportPoolsourceduration12Weeks, + PublicreportPoolsourceduration24Weeks, + PublicreportPoolsourceduration13Months, + PublicreportPoolsourcedurationMoreThan3Months: + return true + default: + return false + } +} + +// useful when testing in other packages +func (e PublicreportPoolsourceduration) All() []PublicreportPoolsourceduration { + return AllPublicreportPoolsourceduration() +} + +func (e PublicreportPoolsourceduration) MarshalText() ([]byte, error) { + return []byte(e), nil +} + +func (e *PublicreportPoolsourceduration) UnmarshalText(text []byte) error { + return e.Scan(text) +} + +func (e PublicreportPoolsourceduration) MarshalBinary() ([]byte, error) { + return []byte(e), nil +} + +func (e *PublicreportPoolsourceduration) UnmarshalBinary(data []byte) error { + return e.Scan(data) +} + +func (e PublicreportPoolsourceduration) Value() (driver.Value, error) { + return string(e), nil +} + +func (e *PublicreportPoolsourceduration) Scan(value any) error { + switch x := value.(type) { + case string: + *e = PublicreportPoolsourceduration(x) + case []byte: + *e = PublicreportPoolsourceduration(x) + case nil: + return fmt.Errorf("cannot nil into PublicreportPoolsourceduration") + default: + return fmt.Errorf("cannot scan type %T: %v", value, value) + } + + if !e.Valid() { + return fmt.Errorf("invalid PublicreportPoolsourceduration value: %s", *e) + } + + return nil +} diff --git a/db/factory/bobfactory_context.bob.go b/db/factory/bobfactory_context.bob.go index f5fa3f8e..69699a39 100644 --- a/db/factory/bobfactory_context.bob.go +++ b/db/factory/bobfactory_context.bob.go @@ -211,6 +211,14 @@ var ( // Relationship Contexts for publicreport.nuisance publicreportNuisanceWithParentsCascadingCtx = newContextual[bool]("publicreportNuisanceWithParentsCascading") + // Relationship Contexts for publicreport.pool + publicreportPoolWithParentsCascadingCtx = newContextual[bool]("publicreportPoolWithParentsCascading") + publicreportPoolRelPoolPhotosCtx = newContextual[bool]("publicreport.pool.publicreport.pool_photo.publicreport.pool_photo.pool_photo_pool_id_fkey") + + // Relationship Contexts for publicreport.pool_photo + publicreportPoolPhotoWithParentsCascadingCtx = newContextual[bool]("publicreportPoolPhotoWithParentsCascading") + publicreportPoolPhotoRelPoolCtx = newContextual[bool]("publicreport.pool.publicreport.pool_photo.publicreport.pool_photo.pool_photo_pool_id_fkey") + // Relationship Contexts for publicreport.quick publicreportQuickWithParentsCascadingCtx = newContextual[bool]("publicreportQuickWithParentsCascading") publicreportQuickRelQuickPhotosCtx = newContextual[bool]("publicreport.quick.publicreport.quick_photo.publicreport.quick_photo.quick_photo_quick_id_fkey") diff --git a/db/factory/bobfactory_main.bob.go b/db/factory/bobfactory_main.bob.go index d70979f9..d1b4d000 100644 --- a/db/factory/bobfactory_main.bob.go +++ b/db/factory/bobfactory_main.bob.go @@ -59,6 +59,8 @@ type Factory struct { baseOauthTokenMods OauthTokenModSlice baseOrganizationMods OrganizationModSlice basePublicreportNuisanceMods PublicreportNuisanceModSlice + basePublicreportPoolMods PublicreportPoolModSlice + basePublicreportPoolPhotoMods PublicreportPoolPhotoModSlice basePublicreportQuickMods PublicreportQuickModSlice basePublicreportQuickPhotoMods PublicreportQuickPhotoModSlice baseRasterColumnMods RasterColumnModSlice @@ -2420,6 +2422,96 @@ func (f *Factory) FromExistingPublicreportNuisance(m *models.PublicreportNuisanc return o } +func (f *Factory) NewPublicreportPool(mods ...PublicreportPoolMod) *PublicreportPoolTemplate { + return f.NewPublicreportPoolWithContext(context.Background(), mods...) +} + +func (f *Factory) NewPublicreportPoolWithContext(ctx context.Context, mods ...PublicreportPoolMod) *PublicreportPoolTemplate { + o := &PublicreportPoolTemplate{f: f} + + if f != nil { + f.basePublicreportPoolMods.Apply(ctx, o) + } + + PublicreportPoolModSlice(mods).Apply(ctx, o) + + return o +} + +func (f *Factory) FromExistingPublicreportPool(m *models.PublicreportPool) *PublicreportPoolTemplate { + o := &PublicreportPoolTemplate{f: f, alreadyPersisted: true} + + o.ID = func() int32 { return m.ID } + o.AccessComments = func() string { return m.AccessComments } + o.AccessGate = func() bool { return m.AccessGate } + o.AccessFence = func() bool { return m.AccessFence } + o.AccessLocked = func() bool { return m.AccessLocked } + o.AccessDog = func() bool { return m.AccessDog } + o.AccessOther = func() bool { return m.AccessOther } + o.Address = func() string { return m.Address } + o.AddressCountry = func() string { return m.AddressCountry } + o.AddressPostCode = func() string { return m.AddressPostCode } + o.AddressPlace = func() string { return m.AddressPlace } + o.AddressStreet = func() string { return m.AddressStreet } + o.AddressRegion = func() string { return m.AddressRegion } + o.Comments = func() string { return m.Comments } + o.Created = func() time.Time { return m.Created } + o.H3cell = func() null.Val[string] { return m.H3cell } + o.HasAdult = func() bool { return m.HasAdult } + o.HasLarvae = func() bool { return m.HasLarvae } + o.HasPupae = func() bool { return m.HasPupae } + o.Location = func() null.Val[string] { return m.Location } + o.MapZoom = func() float64 { return m.MapZoom } + o.OwnerEmail = func() string { return m.OwnerEmail } + o.OwnerName = func() string { return m.OwnerName } + o.OwnerPhone = func() string { return m.OwnerPhone } + o.PublicID = func() string { return m.PublicID } + o.ReporterEmail = func() string { return m.ReporterEmail } + o.ReporterName = func() string { return m.ReporterName } + o.ReporterPhone = func() string { return m.ReporterPhone } + o.Subscribe = func() bool { return m.Subscribe } + + ctx := context.Background() + if len(m.R.PoolPhotos) > 0 { + PublicreportPoolMods.AddExistingPoolPhotos(m.R.PoolPhotos...).Apply(ctx, o) + } + + return o +} + +func (f *Factory) NewPublicreportPoolPhoto(mods ...PublicreportPoolPhotoMod) *PublicreportPoolPhotoTemplate { + return f.NewPublicreportPoolPhotoWithContext(context.Background(), mods...) +} + +func (f *Factory) NewPublicreportPoolPhotoWithContext(ctx context.Context, mods ...PublicreportPoolPhotoMod) *PublicreportPoolPhotoTemplate { + o := &PublicreportPoolPhotoTemplate{f: f} + + if f != nil { + f.basePublicreportPoolPhotoMods.Apply(ctx, o) + } + + PublicreportPoolPhotoModSlice(mods).Apply(ctx, o) + + return o +} + +func (f *Factory) FromExistingPublicreportPoolPhoto(m *models.PublicreportPoolPhoto) *PublicreportPoolPhotoTemplate { + o := &PublicreportPoolPhotoTemplate{f: f, alreadyPersisted: true} + + o.ID = func() int32 { return m.ID } + o.Size = func() int64 { return m.Size } + o.Filename = func() string { return m.Filename } + o.PoolID = func() int32 { return m.PoolID } + o.UUID = func() uuid.UUID { return m.UUID } + + ctx := context.Background() + if m.R.Pool != nil { + PublicreportPoolPhotoMods.WithExistingPool(m.R.Pool).Apply(ctx, o) + } + + return o +} + func (f *Factory) NewPublicreportQuick(mods ...PublicreportQuickMod) *PublicreportQuickTemplate { return f.NewPublicreportQuickWithContext(context.Background(), mods...) } @@ -3009,6 +3101,22 @@ func (f *Factory) AddBasePublicreportNuisanceMod(mods ...PublicreportNuisanceMod f.basePublicreportNuisanceMods = append(f.basePublicreportNuisanceMods, mods...) } +func (f *Factory) ClearBasePublicreportPoolMods() { + f.basePublicreportPoolMods = nil +} + +func (f *Factory) AddBasePublicreportPoolMod(mods ...PublicreportPoolMod) { + f.basePublicreportPoolMods = append(f.basePublicreportPoolMods, mods...) +} + +func (f *Factory) ClearBasePublicreportPoolPhotoMods() { + f.basePublicreportPoolPhotoMods = nil +} + +func (f *Factory) AddBasePublicreportPoolPhotoMod(mods ...PublicreportPoolPhotoMod) { + f.basePublicreportPoolPhotoMods = append(f.basePublicreportPoolPhotoMods, mods...) +} + func (f *Factory) ClearBasePublicreportQuickMods() { f.basePublicreportQuickMods = nil } diff --git a/db/factory/publicreport.pool.bob.go b/db/factory/publicreport.pool.bob.go new file mode 100644 index 00000000..17934a34 --- /dev/null +++ b/db/factory/publicreport.pool.bob.go @@ -0,0 +1,1613 @@ +// Code generated by BobGen psql v0.0.4-0.20260105020634-53e08d840e47+dirty. DO NOT EDIT. +// This file is meant to be re-generated in place and/or deleted at any time. + +package factory + +import ( + "context" + "testing" + "time" + + models "github.com/Gleipnir-Technology/nidus-sync/db/models" + "github.com/aarondl/opt/null" + "github.com/aarondl/opt/omit" + "github.com/aarondl/opt/omitnull" + "github.com/jaswdr/faker/v2" + "github.com/stephenafamo/bob" +) + +type PublicreportPoolMod interface { + Apply(context.Context, *PublicreportPoolTemplate) +} + +type PublicreportPoolModFunc func(context.Context, *PublicreportPoolTemplate) + +func (f PublicreportPoolModFunc) Apply(ctx context.Context, n *PublicreportPoolTemplate) { + f(ctx, n) +} + +type PublicreportPoolModSlice []PublicreportPoolMod + +func (mods PublicreportPoolModSlice) Apply(ctx context.Context, n *PublicreportPoolTemplate) { + for _, f := range mods { + f.Apply(ctx, n) + } +} + +// PublicreportPoolTemplate is an object representing the database table. +// all columns are optional and should be set by mods +type PublicreportPoolTemplate struct { + ID func() int32 + AccessComments func() string + AccessGate func() bool + AccessFence func() bool + AccessLocked func() bool + AccessDog func() bool + AccessOther func() bool + Address func() string + AddressCountry func() string + AddressPostCode func() string + AddressPlace func() string + AddressStreet func() string + AddressRegion func() string + Comments func() string + Created func() time.Time + H3cell func() null.Val[string] + HasAdult func() bool + HasLarvae func() bool + HasPupae func() bool + Location func() null.Val[string] + MapZoom func() float64 + OwnerEmail func() string + OwnerName func() string + OwnerPhone func() string + PublicID func() string + ReporterEmail func() string + ReporterName func() string + ReporterPhone func() string + Subscribe func() bool + + r publicreportPoolR + f *Factory + + alreadyPersisted bool +} + +type publicreportPoolR struct { + PoolPhotos []*publicreportPoolRPoolPhotosR +} + +type publicreportPoolRPoolPhotosR struct { + number int + o *PublicreportPoolPhotoTemplate +} + +// Apply mods to the PublicreportPoolTemplate +func (o *PublicreportPoolTemplate) Apply(ctx context.Context, mods ...PublicreportPoolMod) { + for _, mod := range mods { + mod.Apply(ctx, o) + } +} + +// setModelRels creates and sets the relationships on *models.PublicreportPool +// according to the relationships in the template. Nothing is inserted into the db +func (t PublicreportPoolTemplate) setModelRels(o *models.PublicreportPool) { + if t.r.PoolPhotos != nil { + rel := models.PublicreportPoolPhotoSlice{} + for _, r := range t.r.PoolPhotos { + related := r.o.BuildMany(r.number) + for _, rel := range related { + rel.PoolID = o.ID // h2 + rel.R.Pool = o + } + rel = append(rel, related...) + } + o.R.PoolPhotos = rel + } +} + +// BuildSetter returns an *models.PublicreportPoolSetter +// this does nothing with the relationship templates +func (o PublicreportPoolTemplate) BuildSetter() *models.PublicreportPoolSetter { + m := &models.PublicreportPoolSetter{} + + if o.ID != nil { + val := o.ID() + m.ID = omit.From(val) + } + if o.AccessComments != nil { + val := o.AccessComments() + m.AccessComments = omit.From(val) + } + if o.AccessGate != nil { + val := o.AccessGate() + m.AccessGate = omit.From(val) + } + if o.AccessFence != nil { + val := o.AccessFence() + m.AccessFence = omit.From(val) + } + if o.AccessLocked != nil { + val := o.AccessLocked() + m.AccessLocked = omit.From(val) + } + if o.AccessDog != nil { + val := o.AccessDog() + m.AccessDog = omit.From(val) + } + if o.AccessOther != nil { + val := o.AccessOther() + m.AccessOther = omit.From(val) + } + if o.Address != nil { + val := o.Address() + m.Address = omit.From(val) + } + if o.AddressCountry != nil { + val := o.AddressCountry() + m.AddressCountry = omit.From(val) + } + if o.AddressPostCode != nil { + val := o.AddressPostCode() + m.AddressPostCode = omit.From(val) + } + if o.AddressPlace != nil { + val := o.AddressPlace() + m.AddressPlace = omit.From(val) + } + if o.AddressStreet != nil { + val := o.AddressStreet() + m.AddressStreet = omit.From(val) + } + if o.AddressRegion != nil { + val := o.AddressRegion() + m.AddressRegion = omit.From(val) + } + if o.Comments != nil { + val := o.Comments() + m.Comments = omit.From(val) + } + if o.Created != nil { + val := o.Created() + m.Created = omit.From(val) + } + if o.H3cell != nil { + val := o.H3cell() + m.H3cell = omitnull.FromNull(val) + } + if o.HasAdult != nil { + val := o.HasAdult() + m.HasAdult = omit.From(val) + } + if o.HasLarvae != nil { + val := o.HasLarvae() + m.HasLarvae = omit.From(val) + } + if o.HasPupae != nil { + val := o.HasPupae() + m.HasPupae = omit.From(val) + } + if o.Location != nil { + val := o.Location() + m.Location = omitnull.FromNull(val) + } + if o.MapZoom != nil { + val := o.MapZoom() + m.MapZoom = omit.From(val) + } + if o.OwnerEmail != nil { + val := o.OwnerEmail() + m.OwnerEmail = omit.From(val) + } + if o.OwnerName != nil { + val := o.OwnerName() + m.OwnerName = omit.From(val) + } + if o.OwnerPhone != nil { + val := o.OwnerPhone() + m.OwnerPhone = omit.From(val) + } + if o.PublicID != nil { + val := o.PublicID() + m.PublicID = omit.From(val) + } + if o.ReporterEmail != nil { + val := o.ReporterEmail() + m.ReporterEmail = omit.From(val) + } + if o.ReporterName != nil { + val := o.ReporterName() + m.ReporterName = omit.From(val) + } + if o.ReporterPhone != nil { + val := o.ReporterPhone() + m.ReporterPhone = omit.From(val) + } + if o.Subscribe != nil { + val := o.Subscribe() + m.Subscribe = omit.From(val) + } + + return m +} + +// BuildManySetter returns an []*models.PublicreportPoolSetter +// this does nothing with the relationship templates +func (o PublicreportPoolTemplate) BuildManySetter(number int) []*models.PublicreportPoolSetter { + m := make([]*models.PublicreportPoolSetter, number) + + for i := range m { + m[i] = o.BuildSetter() + } + + return m +} + +// Build returns an *models.PublicreportPool +// Related objects are also created and placed in the .R field +// NOTE: Objects are not inserted into the database. Use PublicreportPoolTemplate.Create +func (o PublicreportPoolTemplate) Build() *models.PublicreportPool { + m := &models.PublicreportPool{} + + if o.ID != nil { + m.ID = o.ID() + } + if o.AccessComments != nil { + m.AccessComments = o.AccessComments() + } + if o.AccessGate != nil { + m.AccessGate = o.AccessGate() + } + if o.AccessFence != nil { + m.AccessFence = o.AccessFence() + } + if o.AccessLocked != nil { + m.AccessLocked = o.AccessLocked() + } + if o.AccessDog != nil { + m.AccessDog = o.AccessDog() + } + if o.AccessOther != nil { + m.AccessOther = o.AccessOther() + } + if o.Address != nil { + m.Address = o.Address() + } + if o.AddressCountry != nil { + m.AddressCountry = o.AddressCountry() + } + if o.AddressPostCode != nil { + m.AddressPostCode = o.AddressPostCode() + } + if o.AddressPlace != nil { + m.AddressPlace = o.AddressPlace() + } + if o.AddressStreet != nil { + m.AddressStreet = o.AddressStreet() + } + if o.AddressRegion != nil { + m.AddressRegion = o.AddressRegion() + } + if o.Comments != nil { + m.Comments = o.Comments() + } + if o.Created != nil { + m.Created = o.Created() + } + if o.H3cell != nil { + m.H3cell = o.H3cell() + } + if o.HasAdult != nil { + m.HasAdult = o.HasAdult() + } + if o.HasLarvae != nil { + m.HasLarvae = o.HasLarvae() + } + if o.HasPupae != nil { + m.HasPupae = o.HasPupae() + } + if o.Location != nil { + m.Location = o.Location() + } + if o.MapZoom != nil { + m.MapZoom = o.MapZoom() + } + if o.OwnerEmail != nil { + m.OwnerEmail = o.OwnerEmail() + } + if o.OwnerName != nil { + m.OwnerName = o.OwnerName() + } + if o.OwnerPhone != nil { + m.OwnerPhone = o.OwnerPhone() + } + if o.PublicID != nil { + m.PublicID = o.PublicID() + } + if o.ReporterEmail != nil { + m.ReporterEmail = o.ReporterEmail() + } + if o.ReporterName != nil { + m.ReporterName = o.ReporterName() + } + if o.ReporterPhone != nil { + m.ReporterPhone = o.ReporterPhone() + } + if o.Subscribe != nil { + m.Subscribe = o.Subscribe() + } + + o.setModelRels(m) + + return m +} + +// BuildMany returns an models.PublicreportPoolSlice +// Related objects are also created and placed in the .R field +// NOTE: Objects are not inserted into the database. Use PublicreportPoolTemplate.CreateMany +func (o PublicreportPoolTemplate) BuildMany(number int) models.PublicreportPoolSlice { + m := make(models.PublicreportPoolSlice, number) + + for i := range m { + m[i] = o.Build() + } + + return m +} + +func ensureCreatablePublicreportPool(m *models.PublicreportPoolSetter) { + if !(m.AccessComments.IsValue()) { + val := random_string(nil) + m.AccessComments = omit.From(val) + } + if !(m.AccessGate.IsValue()) { + val := random_bool(nil) + m.AccessGate = omit.From(val) + } + if !(m.AccessFence.IsValue()) { + val := random_bool(nil) + m.AccessFence = omit.From(val) + } + if !(m.AccessLocked.IsValue()) { + val := random_bool(nil) + m.AccessLocked = omit.From(val) + } + if !(m.AccessDog.IsValue()) { + val := random_bool(nil) + m.AccessDog = omit.From(val) + } + if !(m.AccessOther.IsValue()) { + val := random_bool(nil) + m.AccessOther = omit.From(val) + } + if !(m.Address.IsValue()) { + val := random_string(nil) + m.Address = omit.From(val) + } + if !(m.AddressCountry.IsValue()) { + val := random_string(nil) + m.AddressCountry = omit.From(val) + } + if !(m.AddressPostCode.IsValue()) { + val := random_string(nil) + m.AddressPostCode = omit.From(val) + } + if !(m.AddressPlace.IsValue()) { + val := random_string(nil) + m.AddressPlace = omit.From(val) + } + if !(m.AddressStreet.IsValue()) { + val := random_string(nil) + m.AddressStreet = omit.From(val) + } + if !(m.AddressRegion.IsValue()) { + val := random_string(nil) + m.AddressRegion = omit.From(val) + } + if !(m.Comments.IsValue()) { + val := random_string(nil) + m.Comments = omit.From(val) + } + if !(m.Created.IsValue()) { + val := random_time_Time(nil) + m.Created = omit.From(val) + } + if !(m.HasAdult.IsValue()) { + val := random_bool(nil) + m.HasAdult = omit.From(val) + } + if !(m.HasLarvae.IsValue()) { + val := random_bool(nil) + m.HasLarvae = omit.From(val) + } + if !(m.HasPupae.IsValue()) { + val := random_bool(nil) + m.HasPupae = omit.From(val) + } + if !(m.MapZoom.IsValue()) { + val := random_float64(nil) + m.MapZoom = omit.From(val) + } + if !(m.OwnerEmail.IsValue()) { + val := random_string(nil) + m.OwnerEmail = omit.From(val) + } + if !(m.OwnerName.IsValue()) { + val := random_string(nil) + m.OwnerName = omit.From(val) + } + if !(m.OwnerPhone.IsValue()) { + val := random_string(nil) + m.OwnerPhone = omit.From(val) + } + if !(m.PublicID.IsValue()) { + val := random_string(nil) + m.PublicID = omit.From(val) + } + if !(m.ReporterEmail.IsValue()) { + val := random_string(nil) + m.ReporterEmail = omit.From(val) + } + if !(m.ReporterName.IsValue()) { + val := random_string(nil) + m.ReporterName = omit.From(val) + } + if !(m.ReporterPhone.IsValue()) { + val := random_string(nil) + m.ReporterPhone = omit.From(val) + } + if !(m.Subscribe.IsValue()) { + val := random_bool(nil) + m.Subscribe = omit.From(val) + } +} + +// insertOptRels creates and inserts any optional the relationships on *models.PublicreportPool +// according to the relationships in the template. +// any required relationship should have already exist on the model +func (o *PublicreportPoolTemplate) insertOptRels(ctx context.Context, exec bob.Executor, m *models.PublicreportPool) error { + var err error + + isPoolPhotosDone, _ := publicreportPoolRelPoolPhotosCtx.Value(ctx) + if !isPoolPhotosDone && o.r.PoolPhotos != nil { + ctx = publicreportPoolRelPoolPhotosCtx.WithValue(ctx, true) + for _, r := range o.r.PoolPhotos { + if r.o.alreadyPersisted { + m.R.PoolPhotos = append(m.R.PoolPhotos, r.o.Build()) + } else { + rel0, err := r.o.CreateMany(ctx, exec, r.number) + if err != nil { + return err + } + + err = m.AttachPoolPhotos(ctx, exec, rel0...) + if err != nil { + return err + } + } + } + } + + return err +} + +// Create builds a publicreportPool and inserts it into the database +// Relations objects are also inserted and placed in the .R field +func (o *PublicreportPoolTemplate) Create(ctx context.Context, exec bob.Executor) (*models.PublicreportPool, error) { + var err error + opt := o.BuildSetter() + ensureCreatablePublicreportPool(opt) + + m, err := models.PublicreportPools.Insert(opt).One(ctx, exec) + if err != nil { + return nil, err + } + + if err := o.insertOptRels(ctx, exec, m); err != nil { + return nil, err + } + return m, err +} + +// MustCreate builds a publicreportPool and inserts it into the database +// Relations objects are also inserted and placed in the .R field +// panics if an error occurs +func (o *PublicreportPoolTemplate) MustCreate(ctx context.Context, exec bob.Executor) *models.PublicreportPool { + m, err := o.Create(ctx, exec) + if err != nil { + panic(err) + } + return m +} + +// CreateOrFail builds a publicreportPool 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 *PublicreportPoolTemplate) CreateOrFail(ctx context.Context, tb testing.TB, exec bob.Executor) *models.PublicreportPool { + tb.Helper() + m, err := o.Create(ctx, exec) + if err != nil { + tb.Fatal(err) + return nil + } + return m +} + +// CreateMany builds multiple publicreportPools and inserts them into the database +// Relations objects are also inserted and placed in the .R field +func (o PublicreportPoolTemplate) CreateMany(ctx context.Context, exec bob.Executor, number int) (models.PublicreportPoolSlice, error) { + var err error + m := make(models.PublicreportPoolSlice, number) + + for i := range m { + m[i], err = o.Create(ctx, exec) + if err != nil { + return nil, err + } + } + + return m, nil +} + +// MustCreateMany builds multiple publicreportPools and inserts them into the database +// Relations objects are also inserted and placed in the .R field +// panics if an error occurs +func (o PublicreportPoolTemplate) MustCreateMany(ctx context.Context, exec bob.Executor, number int) models.PublicreportPoolSlice { + m, err := o.CreateMany(ctx, exec, number) + if err != nil { + panic(err) + } + return m +} + +// CreateManyOrFail builds multiple publicreportPools 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 PublicreportPoolTemplate) CreateManyOrFail(ctx context.Context, tb testing.TB, exec bob.Executor, number int) models.PublicreportPoolSlice { + tb.Helper() + m, err := o.CreateMany(ctx, exec, number) + if err != nil { + tb.Fatal(err) + return nil + } + return m +} + +// PublicreportPool has methods that act as mods for the PublicreportPoolTemplate +var PublicreportPoolMods publicreportPoolMods + +type publicreportPoolMods struct{} + +func (m publicreportPoolMods) RandomizeAllColumns(f *faker.Faker) PublicreportPoolMod { + return PublicreportPoolModSlice{ + PublicreportPoolMods.RandomID(f), + PublicreportPoolMods.RandomAccessComments(f), + PublicreportPoolMods.RandomAccessGate(f), + PublicreportPoolMods.RandomAccessFence(f), + PublicreportPoolMods.RandomAccessLocked(f), + PublicreportPoolMods.RandomAccessDog(f), + PublicreportPoolMods.RandomAccessOther(f), + PublicreportPoolMods.RandomAddress(f), + PublicreportPoolMods.RandomAddressCountry(f), + PublicreportPoolMods.RandomAddressPostCode(f), + PublicreportPoolMods.RandomAddressPlace(f), + PublicreportPoolMods.RandomAddressStreet(f), + PublicreportPoolMods.RandomAddressRegion(f), + PublicreportPoolMods.RandomComments(f), + PublicreportPoolMods.RandomCreated(f), + PublicreportPoolMods.RandomH3cell(f), + PublicreportPoolMods.RandomHasAdult(f), + PublicreportPoolMods.RandomHasLarvae(f), + PublicreportPoolMods.RandomHasPupae(f), + PublicreportPoolMods.RandomLocation(f), + PublicreportPoolMods.RandomMapZoom(f), + PublicreportPoolMods.RandomOwnerEmail(f), + PublicreportPoolMods.RandomOwnerName(f), + PublicreportPoolMods.RandomOwnerPhone(f), + PublicreportPoolMods.RandomPublicID(f), + PublicreportPoolMods.RandomReporterEmail(f), + PublicreportPoolMods.RandomReporterName(f), + PublicreportPoolMods.RandomReporterPhone(f), + PublicreportPoolMods.RandomSubscribe(f), + } +} + +// Set the model columns to this value +func (m publicreportPoolMods) ID(val int32) PublicreportPoolMod { + return PublicreportPoolModFunc(func(_ context.Context, o *PublicreportPoolTemplate) { + o.ID = func() int32 { return val } + }) +} + +// Set the Column from the function +func (m publicreportPoolMods) IDFunc(f func() int32) PublicreportPoolMod { + return PublicreportPoolModFunc(func(_ context.Context, o *PublicreportPoolTemplate) { + o.ID = f + }) +} + +// Clear any values for the column +func (m publicreportPoolMods) UnsetID() PublicreportPoolMod { + return PublicreportPoolModFunc(func(_ context.Context, o *PublicreportPoolTemplate) { + o.ID = nil + }) +} + +// Generates a random value for the column using the given faker +// if faker is nil, a default faker is used +func (m publicreportPoolMods) RandomID(f *faker.Faker) PublicreportPoolMod { + return PublicreportPoolModFunc(func(_ context.Context, o *PublicreportPoolTemplate) { + o.ID = func() int32 { + return random_int32(f) + } + }) +} + +// Set the model columns to this value +func (m publicreportPoolMods) AccessComments(val string) PublicreportPoolMod { + return PublicreportPoolModFunc(func(_ context.Context, o *PublicreportPoolTemplate) { + o.AccessComments = func() string { return val } + }) +} + +// Set the Column from the function +func (m publicreportPoolMods) AccessCommentsFunc(f func() string) PublicreportPoolMod { + return PublicreportPoolModFunc(func(_ context.Context, o *PublicreportPoolTemplate) { + o.AccessComments = f + }) +} + +// Clear any values for the column +func (m publicreportPoolMods) UnsetAccessComments() PublicreportPoolMod { + return PublicreportPoolModFunc(func(_ context.Context, o *PublicreportPoolTemplate) { + o.AccessComments = nil + }) +} + +// Generates a random value for the column using the given faker +// if faker is nil, a default faker is used +func (m publicreportPoolMods) RandomAccessComments(f *faker.Faker) PublicreportPoolMod { + return PublicreportPoolModFunc(func(_ context.Context, o *PublicreportPoolTemplate) { + o.AccessComments = func() string { + return random_string(f) + } + }) +} + +// Set the model columns to this value +func (m publicreportPoolMods) AccessGate(val bool) PublicreportPoolMod { + return PublicreportPoolModFunc(func(_ context.Context, o *PublicreportPoolTemplate) { + o.AccessGate = func() bool { return val } + }) +} + +// Set the Column from the function +func (m publicreportPoolMods) AccessGateFunc(f func() bool) PublicreportPoolMod { + return PublicreportPoolModFunc(func(_ context.Context, o *PublicreportPoolTemplate) { + o.AccessGate = f + }) +} + +// Clear any values for the column +func (m publicreportPoolMods) UnsetAccessGate() PublicreportPoolMod { + return PublicreportPoolModFunc(func(_ context.Context, o *PublicreportPoolTemplate) { + o.AccessGate = nil + }) +} + +// Generates a random value for the column using the given faker +// if faker is nil, a default faker is used +func (m publicreportPoolMods) RandomAccessGate(f *faker.Faker) PublicreportPoolMod { + return PublicreportPoolModFunc(func(_ context.Context, o *PublicreportPoolTemplate) { + o.AccessGate = func() bool { + return random_bool(f) + } + }) +} + +// Set the model columns to this value +func (m publicreportPoolMods) AccessFence(val bool) PublicreportPoolMod { + return PublicreportPoolModFunc(func(_ context.Context, o *PublicreportPoolTemplate) { + o.AccessFence = func() bool { return val } + }) +} + +// Set the Column from the function +func (m publicreportPoolMods) AccessFenceFunc(f func() bool) PublicreportPoolMod { + return PublicreportPoolModFunc(func(_ context.Context, o *PublicreportPoolTemplate) { + o.AccessFence = f + }) +} + +// Clear any values for the column +func (m publicreportPoolMods) UnsetAccessFence() PublicreportPoolMod { + return PublicreportPoolModFunc(func(_ context.Context, o *PublicreportPoolTemplate) { + o.AccessFence = nil + }) +} + +// Generates a random value for the column using the given faker +// if faker is nil, a default faker is used +func (m publicreportPoolMods) RandomAccessFence(f *faker.Faker) PublicreportPoolMod { + return PublicreportPoolModFunc(func(_ context.Context, o *PublicreportPoolTemplate) { + o.AccessFence = func() bool { + return random_bool(f) + } + }) +} + +// Set the model columns to this value +func (m publicreportPoolMods) AccessLocked(val bool) PublicreportPoolMod { + return PublicreportPoolModFunc(func(_ context.Context, o *PublicreportPoolTemplate) { + o.AccessLocked = func() bool { return val } + }) +} + +// Set the Column from the function +func (m publicreportPoolMods) AccessLockedFunc(f func() bool) PublicreportPoolMod { + return PublicreportPoolModFunc(func(_ context.Context, o *PublicreportPoolTemplate) { + o.AccessLocked = f + }) +} + +// Clear any values for the column +func (m publicreportPoolMods) UnsetAccessLocked() PublicreportPoolMod { + return PublicreportPoolModFunc(func(_ context.Context, o *PublicreportPoolTemplate) { + o.AccessLocked = nil + }) +} + +// Generates a random value for the column using the given faker +// if faker is nil, a default faker is used +func (m publicreportPoolMods) RandomAccessLocked(f *faker.Faker) PublicreportPoolMod { + return PublicreportPoolModFunc(func(_ context.Context, o *PublicreportPoolTemplate) { + o.AccessLocked = func() bool { + return random_bool(f) + } + }) +} + +// Set the model columns to this value +func (m publicreportPoolMods) AccessDog(val bool) PublicreportPoolMod { + return PublicreportPoolModFunc(func(_ context.Context, o *PublicreportPoolTemplate) { + o.AccessDog = func() bool { return val } + }) +} + +// Set the Column from the function +func (m publicreportPoolMods) AccessDogFunc(f func() bool) PublicreportPoolMod { + return PublicreportPoolModFunc(func(_ context.Context, o *PublicreportPoolTemplate) { + o.AccessDog = f + }) +} + +// Clear any values for the column +func (m publicreportPoolMods) UnsetAccessDog() PublicreportPoolMod { + return PublicreportPoolModFunc(func(_ context.Context, o *PublicreportPoolTemplate) { + o.AccessDog = nil + }) +} + +// Generates a random value for the column using the given faker +// if faker is nil, a default faker is used +func (m publicreportPoolMods) RandomAccessDog(f *faker.Faker) PublicreportPoolMod { + return PublicreportPoolModFunc(func(_ context.Context, o *PublicreportPoolTemplate) { + o.AccessDog = func() bool { + return random_bool(f) + } + }) +} + +// Set the model columns to this value +func (m publicreportPoolMods) AccessOther(val bool) PublicreportPoolMod { + return PublicreportPoolModFunc(func(_ context.Context, o *PublicreportPoolTemplate) { + o.AccessOther = func() bool { return val } + }) +} + +// Set the Column from the function +func (m publicreportPoolMods) AccessOtherFunc(f func() bool) PublicreportPoolMod { + return PublicreportPoolModFunc(func(_ context.Context, o *PublicreportPoolTemplate) { + o.AccessOther = f + }) +} + +// Clear any values for the column +func (m publicreportPoolMods) UnsetAccessOther() PublicreportPoolMod { + return PublicreportPoolModFunc(func(_ context.Context, o *PublicreportPoolTemplate) { + o.AccessOther = nil + }) +} + +// Generates a random value for the column using the given faker +// if faker is nil, a default faker is used +func (m publicreportPoolMods) RandomAccessOther(f *faker.Faker) PublicreportPoolMod { + return PublicreportPoolModFunc(func(_ context.Context, o *PublicreportPoolTemplate) { + o.AccessOther = func() bool { + return random_bool(f) + } + }) +} + +// Set the model columns to this value +func (m publicreportPoolMods) Address(val string) PublicreportPoolMod { + return PublicreportPoolModFunc(func(_ context.Context, o *PublicreportPoolTemplate) { + o.Address = func() string { return val } + }) +} + +// Set the Column from the function +func (m publicreportPoolMods) AddressFunc(f func() string) PublicreportPoolMod { + return PublicreportPoolModFunc(func(_ context.Context, o *PublicreportPoolTemplate) { + o.Address = f + }) +} + +// Clear any values for the column +func (m publicreportPoolMods) UnsetAddress() PublicreportPoolMod { + return PublicreportPoolModFunc(func(_ context.Context, o *PublicreportPoolTemplate) { + o.Address = nil + }) +} + +// Generates a random value for the column using the given faker +// if faker is nil, a default faker is used +func (m publicreportPoolMods) RandomAddress(f *faker.Faker) PublicreportPoolMod { + return PublicreportPoolModFunc(func(_ context.Context, o *PublicreportPoolTemplate) { + o.Address = func() string { + return random_string(f) + } + }) +} + +// Set the model columns to this value +func (m publicreportPoolMods) AddressCountry(val string) PublicreportPoolMod { + return PublicreportPoolModFunc(func(_ context.Context, o *PublicreportPoolTemplate) { + o.AddressCountry = func() string { return val } + }) +} + +// Set the Column from the function +func (m publicreportPoolMods) AddressCountryFunc(f func() string) PublicreportPoolMod { + return PublicreportPoolModFunc(func(_ context.Context, o *PublicreportPoolTemplate) { + o.AddressCountry = f + }) +} + +// Clear any values for the column +func (m publicreportPoolMods) UnsetAddressCountry() PublicreportPoolMod { + return PublicreportPoolModFunc(func(_ context.Context, o *PublicreportPoolTemplate) { + o.AddressCountry = nil + }) +} + +// Generates a random value for the column using the given faker +// if faker is nil, a default faker is used +func (m publicreportPoolMods) RandomAddressCountry(f *faker.Faker) PublicreportPoolMod { + return PublicreportPoolModFunc(func(_ context.Context, o *PublicreportPoolTemplate) { + o.AddressCountry = func() string { + return random_string(f) + } + }) +} + +// Set the model columns to this value +func (m publicreportPoolMods) AddressPostCode(val string) PublicreportPoolMod { + return PublicreportPoolModFunc(func(_ context.Context, o *PublicreportPoolTemplate) { + o.AddressPostCode = func() string { return val } + }) +} + +// Set the Column from the function +func (m publicreportPoolMods) AddressPostCodeFunc(f func() string) PublicreportPoolMod { + return PublicreportPoolModFunc(func(_ context.Context, o *PublicreportPoolTemplate) { + o.AddressPostCode = f + }) +} + +// Clear any values for the column +func (m publicreportPoolMods) UnsetAddressPostCode() PublicreportPoolMod { + return PublicreportPoolModFunc(func(_ context.Context, o *PublicreportPoolTemplate) { + o.AddressPostCode = nil + }) +} + +// Generates a random value for the column using the given faker +// if faker is nil, a default faker is used +func (m publicreportPoolMods) RandomAddressPostCode(f *faker.Faker) PublicreportPoolMod { + return PublicreportPoolModFunc(func(_ context.Context, o *PublicreportPoolTemplate) { + o.AddressPostCode = func() string { + return random_string(f) + } + }) +} + +// Set the model columns to this value +func (m publicreportPoolMods) AddressPlace(val string) PublicreportPoolMod { + return PublicreportPoolModFunc(func(_ context.Context, o *PublicreportPoolTemplate) { + o.AddressPlace = func() string { return val } + }) +} + +// Set the Column from the function +func (m publicreportPoolMods) AddressPlaceFunc(f func() string) PublicreportPoolMod { + return PublicreportPoolModFunc(func(_ context.Context, o *PublicreportPoolTemplate) { + o.AddressPlace = f + }) +} + +// Clear any values for the column +func (m publicreportPoolMods) UnsetAddressPlace() PublicreportPoolMod { + return PublicreportPoolModFunc(func(_ context.Context, o *PublicreportPoolTemplate) { + o.AddressPlace = nil + }) +} + +// Generates a random value for the column using the given faker +// if faker is nil, a default faker is used +func (m publicreportPoolMods) RandomAddressPlace(f *faker.Faker) PublicreportPoolMod { + return PublicreportPoolModFunc(func(_ context.Context, o *PublicreportPoolTemplate) { + o.AddressPlace = func() string { + return random_string(f) + } + }) +} + +// Set the model columns to this value +func (m publicreportPoolMods) AddressStreet(val string) PublicreportPoolMod { + return PublicreportPoolModFunc(func(_ context.Context, o *PublicreportPoolTemplate) { + o.AddressStreet = func() string { return val } + }) +} + +// Set the Column from the function +func (m publicreportPoolMods) AddressStreetFunc(f func() string) PublicreportPoolMod { + return PublicreportPoolModFunc(func(_ context.Context, o *PublicreportPoolTemplate) { + o.AddressStreet = f + }) +} + +// Clear any values for the column +func (m publicreportPoolMods) UnsetAddressStreet() PublicreportPoolMod { + return PublicreportPoolModFunc(func(_ context.Context, o *PublicreportPoolTemplate) { + o.AddressStreet = nil + }) +} + +// Generates a random value for the column using the given faker +// if faker is nil, a default faker is used +func (m publicreportPoolMods) RandomAddressStreet(f *faker.Faker) PublicreportPoolMod { + return PublicreportPoolModFunc(func(_ context.Context, o *PublicreportPoolTemplate) { + o.AddressStreet = func() string { + return random_string(f) + } + }) +} + +// Set the model columns to this value +func (m publicreportPoolMods) AddressRegion(val string) PublicreportPoolMod { + return PublicreportPoolModFunc(func(_ context.Context, o *PublicreportPoolTemplate) { + o.AddressRegion = func() string { return val } + }) +} + +// Set the Column from the function +func (m publicreportPoolMods) AddressRegionFunc(f func() string) PublicreportPoolMod { + return PublicreportPoolModFunc(func(_ context.Context, o *PublicreportPoolTemplate) { + o.AddressRegion = f + }) +} + +// Clear any values for the column +func (m publicreportPoolMods) UnsetAddressRegion() PublicreportPoolMod { + return PublicreportPoolModFunc(func(_ context.Context, o *PublicreportPoolTemplate) { + o.AddressRegion = nil + }) +} + +// Generates a random value for the column using the given faker +// if faker is nil, a default faker is used +func (m publicreportPoolMods) RandomAddressRegion(f *faker.Faker) PublicreportPoolMod { + return PublicreportPoolModFunc(func(_ context.Context, o *PublicreportPoolTemplate) { + o.AddressRegion = func() string { + return random_string(f) + } + }) +} + +// Set the model columns to this value +func (m publicreportPoolMods) Comments(val string) PublicreportPoolMod { + return PublicreportPoolModFunc(func(_ context.Context, o *PublicreportPoolTemplate) { + o.Comments = func() string { return val } + }) +} + +// Set the Column from the function +func (m publicreportPoolMods) CommentsFunc(f func() string) PublicreportPoolMod { + return PublicreportPoolModFunc(func(_ context.Context, o *PublicreportPoolTemplate) { + o.Comments = f + }) +} + +// Clear any values for the column +func (m publicreportPoolMods) UnsetComments() PublicreportPoolMod { + return PublicreportPoolModFunc(func(_ context.Context, o *PublicreportPoolTemplate) { + o.Comments = nil + }) +} + +// Generates a random value for the column using the given faker +// if faker is nil, a default faker is used +func (m publicreportPoolMods) RandomComments(f *faker.Faker) PublicreportPoolMod { + return PublicreportPoolModFunc(func(_ context.Context, o *PublicreportPoolTemplate) { + o.Comments = func() string { + return random_string(f) + } + }) +} + +// Set the model columns to this value +func (m publicreportPoolMods) Created(val time.Time) PublicreportPoolMod { + return PublicreportPoolModFunc(func(_ context.Context, o *PublicreportPoolTemplate) { + o.Created = func() time.Time { return val } + }) +} + +// Set the Column from the function +func (m publicreportPoolMods) CreatedFunc(f func() time.Time) PublicreportPoolMod { + return PublicreportPoolModFunc(func(_ context.Context, o *PublicreportPoolTemplate) { + o.Created = f + }) +} + +// Clear any values for the column +func (m publicreportPoolMods) UnsetCreated() PublicreportPoolMod { + return PublicreportPoolModFunc(func(_ context.Context, o *PublicreportPoolTemplate) { + o.Created = nil + }) +} + +// Generates a random value for the column using the given faker +// if faker is nil, a default faker is used +func (m publicreportPoolMods) RandomCreated(f *faker.Faker) PublicreportPoolMod { + return PublicreportPoolModFunc(func(_ context.Context, o *PublicreportPoolTemplate) { + o.Created = func() time.Time { + return random_time_Time(f) + } + }) +} + +// Set the model columns to this value +func (m publicreportPoolMods) H3cell(val null.Val[string]) PublicreportPoolMod { + return PublicreportPoolModFunc(func(_ context.Context, o *PublicreportPoolTemplate) { + o.H3cell = func() null.Val[string] { return val } + }) +} + +// Set the Column from the function +func (m publicreportPoolMods) H3cellFunc(f func() null.Val[string]) PublicreportPoolMod { + return PublicreportPoolModFunc(func(_ context.Context, o *PublicreportPoolTemplate) { + o.H3cell = f + }) +} + +// Clear any values for the column +func (m publicreportPoolMods) UnsetH3cell() PublicreportPoolMod { + return PublicreportPoolModFunc(func(_ context.Context, o *PublicreportPoolTemplate) { + 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 publicreportPoolMods) RandomH3cell(f *faker.Faker) PublicreportPoolMod { + return PublicreportPoolModFunc(func(_ context.Context, o *PublicreportPoolTemplate) { + 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 publicreportPoolMods) RandomH3cellNotNull(f *faker.Faker) PublicreportPoolMod { + return PublicreportPoolModFunc(func(_ context.Context, o *PublicreportPoolTemplate) { + o.H3cell = func() null.Val[string] { + if f == nil { + f = &defaultFaker + } + + val := random_string(f) + return null.From(val) + } + }) +} + +// Set the model columns to this value +func (m publicreportPoolMods) HasAdult(val bool) PublicreportPoolMod { + return PublicreportPoolModFunc(func(_ context.Context, o *PublicreportPoolTemplate) { + o.HasAdult = func() bool { return val } + }) +} + +// Set the Column from the function +func (m publicreportPoolMods) HasAdultFunc(f func() bool) PublicreportPoolMod { + return PublicreportPoolModFunc(func(_ context.Context, o *PublicreportPoolTemplate) { + o.HasAdult = f + }) +} + +// Clear any values for the column +func (m publicreportPoolMods) UnsetHasAdult() PublicreportPoolMod { + return PublicreportPoolModFunc(func(_ context.Context, o *PublicreportPoolTemplate) { + o.HasAdult = nil + }) +} + +// Generates a random value for the column using the given faker +// if faker is nil, a default faker is used +func (m publicreportPoolMods) RandomHasAdult(f *faker.Faker) PublicreportPoolMod { + return PublicreportPoolModFunc(func(_ context.Context, o *PublicreportPoolTemplate) { + o.HasAdult = func() bool { + return random_bool(f) + } + }) +} + +// Set the model columns to this value +func (m publicreportPoolMods) HasLarvae(val bool) PublicreportPoolMod { + return PublicreportPoolModFunc(func(_ context.Context, o *PublicreportPoolTemplate) { + o.HasLarvae = func() bool { return val } + }) +} + +// Set the Column from the function +func (m publicreportPoolMods) HasLarvaeFunc(f func() bool) PublicreportPoolMod { + return PublicreportPoolModFunc(func(_ context.Context, o *PublicreportPoolTemplate) { + o.HasLarvae = f + }) +} + +// Clear any values for the column +func (m publicreportPoolMods) UnsetHasLarvae() PublicreportPoolMod { + return PublicreportPoolModFunc(func(_ context.Context, o *PublicreportPoolTemplate) { + o.HasLarvae = nil + }) +} + +// Generates a random value for the column using the given faker +// if faker is nil, a default faker is used +func (m publicreportPoolMods) RandomHasLarvae(f *faker.Faker) PublicreportPoolMod { + return PublicreportPoolModFunc(func(_ context.Context, o *PublicreportPoolTemplate) { + o.HasLarvae = func() bool { + return random_bool(f) + } + }) +} + +// Set the model columns to this value +func (m publicreportPoolMods) HasPupae(val bool) PublicreportPoolMod { + return PublicreportPoolModFunc(func(_ context.Context, o *PublicreportPoolTemplate) { + o.HasPupae = func() bool { return val } + }) +} + +// Set the Column from the function +func (m publicreportPoolMods) HasPupaeFunc(f func() bool) PublicreportPoolMod { + return PublicreportPoolModFunc(func(_ context.Context, o *PublicreportPoolTemplate) { + o.HasPupae = f + }) +} + +// Clear any values for the column +func (m publicreportPoolMods) UnsetHasPupae() PublicreportPoolMod { + return PublicreportPoolModFunc(func(_ context.Context, o *PublicreportPoolTemplate) { + o.HasPupae = nil + }) +} + +// Generates a random value for the column using the given faker +// if faker is nil, a default faker is used +func (m publicreportPoolMods) RandomHasPupae(f *faker.Faker) PublicreportPoolMod { + return PublicreportPoolModFunc(func(_ context.Context, o *PublicreportPoolTemplate) { + o.HasPupae = func() bool { + return random_bool(f) + } + }) +} + +// Set the model columns to this value +func (m publicreportPoolMods) Location(val null.Val[string]) PublicreportPoolMod { + return PublicreportPoolModFunc(func(_ context.Context, o *PublicreportPoolTemplate) { + o.Location = func() null.Val[string] { return val } + }) +} + +// Set the Column from the function +func (m publicreportPoolMods) LocationFunc(f func() null.Val[string]) PublicreportPoolMod { + return PublicreportPoolModFunc(func(_ context.Context, o *PublicreportPoolTemplate) { + o.Location = f + }) +} + +// Clear any values for the column +func (m publicreportPoolMods) UnsetLocation() PublicreportPoolMod { + return PublicreportPoolModFunc(func(_ context.Context, o *PublicreportPoolTemplate) { + o.Location = 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 publicreportPoolMods) RandomLocation(f *faker.Faker) PublicreportPoolMod { + return PublicreportPoolModFunc(func(_ context.Context, o *PublicreportPoolTemplate) { + o.Location = 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 publicreportPoolMods) RandomLocationNotNull(f *faker.Faker) PublicreportPoolMod { + return PublicreportPoolModFunc(func(_ context.Context, o *PublicreportPoolTemplate) { + o.Location = func() null.Val[string] { + if f == nil { + f = &defaultFaker + } + + val := random_string(f) + return null.From(val) + } + }) +} + +// Set the model columns to this value +func (m publicreportPoolMods) MapZoom(val float64) PublicreportPoolMod { + return PublicreportPoolModFunc(func(_ context.Context, o *PublicreportPoolTemplate) { + o.MapZoom = func() float64 { return val } + }) +} + +// Set the Column from the function +func (m publicreportPoolMods) MapZoomFunc(f func() float64) PublicreportPoolMod { + return PublicreportPoolModFunc(func(_ context.Context, o *PublicreportPoolTemplate) { + o.MapZoom = f + }) +} + +// Clear any values for the column +func (m publicreportPoolMods) UnsetMapZoom() PublicreportPoolMod { + return PublicreportPoolModFunc(func(_ context.Context, o *PublicreportPoolTemplate) { + o.MapZoom = nil + }) +} + +// Generates a random value for the column using the given faker +// if faker is nil, a default faker is used +func (m publicreportPoolMods) RandomMapZoom(f *faker.Faker) PublicreportPoolMod { + return PublicreportPoolModFunc(func(_ context.Context, o *PublicreportPoolTemplate) { + o.MapZoom = func() float64 { + return random_float64(f) + } + }) +} + +// Set the model columns to this value +func (m publicreportPoolMods) OwnerEmail(val string) PublicreportPoolMod { + return PublicreportPoolModFunc(func(_ context.Context, o *PublicreportPoolTemplate) { + o.OwnerEmail = func() string { return val } + }) +} + +// Set the Column from the function +func (m publicreportPoolMods) OwnerEmailFunc(f func() string) PublicreportPoolMod { + return PublicreportPoolModFunc(func(_ context.Context, o *PublicreportPoolTemplate) { + o.OwnerEmail = f + }) +} + +// Clear any values for the column +func (m publicreportPoolMods) UnsetOwnerEmail() PublicreportPoolMod { + return PublicreportPoolModFunc(func(_ context.Context, o *PublicreportPoolTemplate) { + o.OwnerEmail = nil + }) +} + +// Generates a random value for the column using the given faker +// if faker is nil, a default faker is used +func (m publicreportPoolMods) RandomOwnerEmail(f *faker.Faker) PublicreportPoolMod { + return PublicreportPoolModFunc(func(_ context.Context, o *PublicreportPoolTemplate) { + o.OwnerEmail = func() string { + return random_string(f) + } + }) +} + +// Set the model columns to this value +func (m publicreportPoolMods) OwnerName(val string) PublicreportPoolMod { + return PublicreportPoolModFunc(func(_ context.Context, o *PublicreportPoolTemplate) { + o.OwnerName = func() string { return val } + }) +} + +// Set the Column from the function +func (m publicreportPoolMods) OwnerNameFunc(f func() string) PublicreportPoolMod { + return PublicreportPoolModFunc(func(_ context.Context, o *PublicreportPoolTemplate) { + o.OwnerName = f + }) +} + +// Clear any values for the column +func (m publicreportPoolMods) UnsetOwnerName() PublicreportPoolMod { + return PublicreportPoolModFunc(func(_ context.Context, o *PublicreportPoolTemplate) { + o.OwnerName = nil + }) +} + +// Generates a random value for the column using the given faker +// if faker is nil, a default faker is used +func (m publicreportPoolMods) RandomOwnerName(f *faker.Faker) PublicreportPoolMod { + return PublicreportPoolModFunc(func(_ context.Context, o *PublicreportPoolTemplate) { + o.OwnerName = func() string { + return random_string(f) + } + }) +} + +// Set the model columns to this value +func (m publicreportPoolMods) OwnerPhone(val string) PublicreportPoolMod { + return PublicreportPoolModFunc(func(_ context.Context, o *PublicreportPoolTemplate) { + o.OwnerPhone = func() string { return val } + }) +} + +// Set the Column from the function +func (m publicreportPoolMods) OwnerPhoneFunc(f func() string) PublicreportPoolMod { + return PublicreportPoolModFunc(func(_ context.Context, o *PublicreportPoolTemplate) { + o.OwnerPhone = f + }) +} + +// Clear any values for the column +func (m publicreportPoolMods) UnsetOwnerPhone() PublicreportPoolMod { + return PublicreportPoolModFunc(func(_ context.Context, o *PublicreportPoolTemplate) { + o.OwnerPhone = nil + }) +} + +// Generates a random value for the column using the given faker +// if faker is nil, a default faker is used +func (m publicreportPoolMods) RandomOwnerPhone(f *faker.Faker) PublicreportPoolMod { + return PublicreportPoolModFunc(func(_ context.Context, o *PublicreportPoolTemplate) { + o.OwnerPhone = func() string { + return random_string(f) + } + }) +} + +// Set the model columns to this value +func (m publicreportPoolMods) PublicID(val string) PublicreportPoolMod { + return PublicreportPoolModFunc(func(_ context.Context, o *PublicreportPoolTemplate) { + o.PublicID = func() string { return val } + }) +} + +// Set the Column from the function +func (m publicreportPoolMods) PublicIDFunc(f func() string) PublicreportPoolMod { + return PublicreportPoolModFunc(func(_ context.Context, o *PublicreportPoolTemplate) { + o.PublicID = f + }) +} + +// Clear any values for the column +func (m publicreportPoolMods) UnsetPublicID() PublicreportPoolMod { + return PublicreportPoolModFunc(func(_ context.Context, o *PublicreportPoolTemplate) { + o.PublicID = nil + }) +} + +// Generates a random value for the column using the given faker +// if faker is nil, a default faker is used +func (m publicreportPoolMods) RandomPublicID(f *faker.Faker) PublicreportPoolMod { + return PublicreportPoolModFunc(func(_ context.Context, o *PublicreportPoolTemplate) { + o.PublicID = func() string { + return random_string(f) + } + }) +} + +// Set the model columns to this value +func (m publicreportPoolMods) ReporterEmail(val string) PublicreportPoolMod { + return PublicreportPoolModFunc(func(_ context.Context, o *PublicreportPoolTemplate) { + o.ReporterEmail = func() string { return val } + }) +} + +// Set the Column from the function +func (m publicreportPoolMods) ReporterEmailFunc(f func() string) PublicreportPoolMod { + return PublicreportPoolModFunc(func(_ context.Context, o *PublicreportPoolTemplate) { + o.ReporterEmail = f + }) +} + +// Clear any values for the column +func (m publicreportPoolMods) UnsetReporterEmail() PublicreportPoolMod { + return PublicreportPoolModFunc(func(_ context.Context, o *PublicreportPoolTemplate) { + o.ReporterEmail = nil + }) +} + +// Generates a random value for the column using the given faker +// if faker is nil, a default faker is used +func (m publicreportPoolMods) RandomReporterEmail(f *faker.Faker) PublicreportPoolMod { + return PublicreportPoolModFunc(func(_ context.Context, o *PublicreportPoolTemplate) { + o.ReporterEmail = func() string { + return random_string(f) + } + }) +} + +// Set the model columns to this value +func (m publicreportPoolMods) ReporterName(val string) PublicreportPoolMod { + return PublicreportPoolModFunc(func(_ context.Context, o *PublicreportPoolTemplate) { + o.ReporterName = func() string { return val } + }) +} + +// Set the Column from the function +func (m publicreportPoolMods) ReporterNameFunc(f func() string) PublicreportPoolMod { + return PublicreportPoolModFunc(func(_ context.Context, o *PublicreportPoolTemplate) { + o.ReporterName = f + }) +} + +// Clear any values for the column +func (m publicreportPoolMods) UnsetReporterName() PublicreportPoolMod { + return PublicreportPoolModFunc(func(_ context.Context, o *PublicreportPoolTemplate) { + o.ReporterName = nil + }) +} + +// Generates a random value for the column using the given faker +// if faker is nil, a default faker is used +func (m publicreportPoolMods) RandomReporterName(f *faker.Faker) PublicreportPoolMod { + return PublicreportPoolModFunc(func(_ context.Context, o *PublicreportPoolTemplate) { + o.ReporterName = func() string { + return random_string(f) + } + }) +} + +// Set the model columns to this value +func (m publicreportPoolMods) ReporterPhone(val string) PublicreportPoolMod { + return PublicreportPoolModFunc(func(_ context.Context, o *PublicreportPoolTemplate) { + o.ReporterPhone = func() string { return val } + }) +} + +// Set the Column from the function +func (m publicreportPoolMods) ReporterPhoneFunc(f func() string) PublicreportPoolMod { + return PublicreportPoolModFunc(func(_ context.Context, o *PublicreportPoolTemplate) { + o.ReporterPhone = f + }) +} + +// Clear any values for the column +func (m publicreportPoolMods) UnsetReporterPhone() PublicreportPoolMod { + return PublicreportPoolModFunc(func(_ context.Context, o *PublicreportPoolTemplate) { + o.ReporterPhone = nil + }) +} + +// Generates a random value for the column using the given faker +// if faker is nil, a default faker is used +func (m publicreportPoolMods) RandomReporterPhone(f *faker.Faker) PublicreportPoolMod { + return PublicreportPoolModFunc(func(_ context.Context, o *PublicreportPoolTemplate) { + o.ReporterPhone = func() string { + return random_string(f) + } + }) +} + +// Set the model columns to this value +func (m publicreportPoolMods) Subscribe(val bool) PublicreportPoolMod { + return PublicreportPoolModFunc(func(_ context.Context, o *PublicreportPoolTemplate) { + o.Subscribe = func() bool { return val } + }) +} + +// Set the Column from the function +func (m publicreportPoolMods) SubscribeFunc(f func() bool) PublicreportPoolMod { + return PublicreportPoolModFunc(func(_ context.Context, o *PublicreportPoolTemplate) { + o.Subscribe = f + }) +} + +// Clear any values for the column +func (m publicreportPoolMods) UnsetSubscribe() PublicreportPoolMod { + return PublicreportPoolModFunc(func(_ context.Context, o *PublicreportPoolTemplate) { + o.Subscribe = nil + }) +} + +// Generates a random value for the column using the given faker +// if faker is nil, a default faker is used +func (m publicreportPoolMods) RandomSubscribe(f *faker.Faker) PublicreportPoolMod { + return PublicreportPoolModFunc(func(_ context.Context, o *PublicreportPoolTemplate) { + o.Subscribe = func() bool { + return random_bool(f) + } + }) +} + +func (m publicreportPoolMods) WithParentsCascading() PublicreportPoolMod { + return PublicreportPoolModFunc(func(ctx context.Context, o *PublicreportPoolTemplate) { + if isDone, _ := publicreportPoolWithParentsCascadingCtx.Value(ctx); isDone { + return + } + ctx = publicreportPoolWithParentsCascadingCtx.WithValue(ctx, true) + }) +} + +func (m publicreportPoolMods) WithPoolPhotos(number int, related *PublicreportPoolPhotoTemplate) PublicreportPoolMod { + return PublicreportPoolModFunc(func(ctx context.Context, o *PublicreportPoolTemplate) { + o.r.PoolPhotos = []*publicreportPoolRPoolPhotosR{{ + number: number, + o: related, + }} + }) +} + +func (m publicreportPoolMods) WithNewPoolPhotos(number int, mods ...PublicreportPoolPhotoMod) PublicreportPoolMod { + return PublicreportPoolModFunc(func(ctx context.Context, o *PublicreportPoolTemplate) { + related := o.f.NewPublicreportPoolPhotoWithContext(ctx, mods...) + m.WithPoolPhotos(number, related).Apply(ctx, o) + }) +} + +func (m publicreportPoolMods) AddPoolPhotos(number int, related *PublicreportPoolPhotoTemplate) PublicreportPoolMod { + return PublicreportPoolModFunc(func(ctx context.Context, o *PublicreportPoolTemplate) { + o.r.PoolPhotos = append(o.r.PoolPhotos, &publicreportPoolRPoolPhotosR{ + number: number, + o: related, + }) + }) +} + +func (m publicreportPoolMods) AddNewPoolPhotos(number int, mods ...PublicreportPoolPhotoMod) PublicreportPoolMod { + return PublicreportPoolModFunc(func(ctx context.Context, o *PublicreportPoolTemplate) { + related := o.f.NewPublicreportPoolPhotoWithContext(ctx, mods...) + m.AddPoolPhotos(number, related).Apply(ctx, o) + }) +} + +func (m publicreportPoolMods) AddExistingPoolPhotos(existingModels ...*models.PublicreportPoolPhoto) PublicreportPoolMod { + return PublicreportPoolModFunc(func(ctx context.Context, o *PublicreportPoolTemplate) { + for _, em := range existingModels { + o.r.PoolPhotos = append(o.r.PoolPhotos, &publicreportPoolRPoolPhotosR{ + o: o.f.FromExistingPublicreportPoolPhoto(em), + }) + } + }) +} + +func (m publicreportPoolMods) WithoutPoolPhotos() PublicreportPoolMod { + return PublicreportPoolModFunc(func(ctx context.Context, o *PublicreportPoolTemplate) { + o.r.PoolPhotos = nil + }) +} diff --git a/db/factory/publicreport.pool_photo.bob.go b/db/factory/publicreport.pool_photo.bob.go new file mode 100644 index 00000000..a0a289d0 --- /dev/null +++ b/db/factory/publicreport.pool_photo.bob.go @@ -0,0 +1,498 @@ +// Code generated by BobGen psql v0.0.4-0.20260105020634-53e08d840e47+dirty. DO NOT EDIT. +// This file is meant to be re-generated in place and/or deleted at any time. + +package factory + +import ( + "context" + "testing" + + models "github.com/Gleipnir-Technology/nidus-sync/db/models" + "github.com/aarondl/opt/omit" + "github.com/google/uuid" + "github.com/jaswdr/faker/v2" + "github.com/stephenafamo/bob" +) + +type PublicreportPoolPhotoMod interface { + Apply(context.Context, *PublicreportPoolPhotoTemplate) +} + +type PublicreportPoolPhotoModFunc func(context.Context, *PublicreportPoolPhotoTemplate) + +func (f PublicreportPoolPhotoModFunc) Apply(ctx context.Context, n *PublicreportPoolPhotoTemplate) { + f(ctx, n) +} + +type PublicreportPoolPhotoModSlice []PublicreportPoolPhotoMod + +func (mods PublicreportPoolPhotoModSlice) Apply(ctx context.Context, n *PublicreportPoolPhotoTemplate) { + for _, f := range mods { + f.Apply(ctx, n) + } +} + +// PublicreportPoolPhotoTemplate is an object representing the database table. +// all columns are optional and should be set by mods +type PublicreportPoolPhotoTemplate struct { + ID func() int32 + Size func() int64 + Filename func() string + PoolID func() int32 + UUID func() uuid.UUID + + r publicreportPoolPhotoR + f *Factory + + alreadyPersisted bool +} + +type publicreportPoolPhotoR struct { + Pool *publicreportPoolPhotoRPoolR +} + +type publicreportPoolPhotoRPoolR struct { + o *PublicreportPoolTemplate +} + +// Apply mods to the PublicreportPoolPhotoTemplate +func (o *PublicreportPoolPhotoTemplate) Apply(ctx context.Context, mods ...PublicreportPoolPhotoMod) { + for _, mod := range mods { + mod.Apply(ctx, o) + } +} + +// setModelRels creates and sets the relationships on *models.PublicreportPoolPhoto +// according to the relationships in the template. Nothing is inserted into the db +func (t PublicreportPoolPhotoTemplate) setModelRels(o *models.PublicreportPoolPhoto) { + if t.r.Pool != nil { + rel := t.r.Pool.o.Build() + rel.R.PoolPhotos = append(rel.R.PoolPhotos, o) + o.PoolID = rel.ID // h2 + o.R.Pool = rel + } +} + +// BuildSetter returns an *models.PublicreportPoolPhotoSetter +// this does nothing with the relationship templates +func (o PublicreportPoolPhotoTemplate) BuildSetter() *models.PublicreportPoolPhotoSetter { + m := &models.PublicreportPoolPhotoSetter{} + + if o.ID != nil { + val := o.ID() + m.ID = omit.From(val) + } + if o.Size != nil { + val := o.Size() + m.Size = omit.From(val) + } + if o.Filename != nil { + val := o.Filename() + m.Filename = omit.From(val) + } + if o.PoolID != nil { + val := o.PoolID() + m.PoolID = omit.From(val) + } + if o.UUID != nil { + val := o.UUID() + m.UUID = omit.From(val) + } + + return m +} + +// BuildManySetter returns an []*models.PublicreportPoolPhotoSetter +// this does nothing with the relationship templates +func (o PublicreportPoolPhotoTemplate) BuildManySetter(number int) []*models.PublicreportPoolPhotoSetter { + m := make([]*models.PublicreportPoolPhotoSetter, number) + + for i := range m { + m[i] = o.BuildSetter() + } + + return m +} + +// Build returns an *models.PublicreportPoolPhoto +// Related objects are also created and placed in the .R field +// NOTE: Objects are not inserted into the database. Use PublicreportPoolPhotoTemplate.Create +func (o PublicreportPoolPhotoTemplate) Build() *models.PublicreportPoolPhoto { + m := &models.PublicreportPoolPhoto{} + + if o.ID != nil { + m.ID = o.ID() + } + if o.Size != nil { + m.Size = o.Size() + } + if o.Filename != nil { + m.Filename = o.Filename() + } + if o.PoolID != nil { + m.PoolID = o.PoolID() + } + if o.UUID != nil { + m.UUID = o.UUID() + } + + o.setModelRels(m) + + return m +} + +// BuildMany returns an models.PublicreportPoolPhotoSlice +// Related objects are also created and placed in the .R field +// NOTE: Objects are not inserted into the database. Use PublicreportPoolPhotoTemplate.CreateMany +func (o PublicreportPoolPhotoTemplate) BuildMany(number int) models.PublicreportPoolPhotoSlice { + m := make(models.PublicreportPoolPhotoSlice, number) + + for i := range m { + m[i] = o.Build() + } + + return m +} + +func ensureCreatablePublicreportPoolPhoto(m *models.PublicreportPoolPhotoSetter) { + if !(m.Size.IsValue()) { + val := random_int64(nil) + m.Size = omit.From(val) + } + if !(m.Filename.IsValue()) { + val := random_string(nil) + m.Filename = omit.From(val) + } + if !(m.PoolID.IsValue()) { + val := random_int32(nil) + m.PoolID = omit.From(val) + } + if !(m.UUID.IsValue()) { + val := random_uuid_UUID(nil) + m.UUID = omit.From(val) + } +} + +// insertOptRels creates and inserts any optional the relationships on *models.PublicreportPoolPhoto +// according to the relationships in the template. +// any required relationship should have already exist on the model +func (o *PublicreportPoolPhotoTemplate) insertOptRels(ctx context.Context, exec bob.Executor, m *models.PublicreportPoolPhoto) error { + var err error + + return err +} + +// Create builds a publicreportPoolPhoto and inserts it into the database +// Relations objects are also inserted and placed in the .R field +func (o *PublicreportPoolPhotoTemplate) Create(ctx context.Context, exec bob.Executor) (*models.PublicreportPoolPhoto, error) { + var err error + opt := o.BuildSetter() + ensureCreatablePublicreportPoolPhoto(opt) + + if o.r.Pool == nil { + PublicreportPoolPhotoMods.WithNewPool().Apply(ctx, o) + } + + var rel0 *models.PublicreportPool + + if o.r.Pool.o.alreadyPersisted { + rel0 = o.r.Pool.o.Build() + } else { + rel0, err = o.r.Pool.o.Create(ctx, exec) + if err != nil { + return nil, err + } + } + + opt.PoolID = omit.From(rel0.ID) + + m, err := models.PublicreportPoolPhotos.Insert(opt).One(ctx, exec) + if err != nil { + return nil, err + } + + m.R.Pool = rel0 + + if err := o.insertOptRels(ctx, exec, m); err != nil { + return nil, err + } + return m, err +} + +// MustCreate builds a publicreportPoolPhoto and inserts it into the database +// Relations objects are also inserted and placed in the .R field +// panics if an error occurs +func (o *PublicreportPoolPhotoTemplate) MustCreate(ctx context.Context, exec bob.Executor) *models.PublicreportPoolPhoto { + m, err := o.Create(ctx, exec) + if err != nil { + panic(err) + } + return m +} + +// CreateOrFail builds a publicreportPoolPhoto 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 *PublicreportPoolPhotoTemplate) CreateOrFail(ctx context.Context, tb testing.TB, exec bob.Executor) *models.PublicreportPoolPhoto { + tb.Helper() + m, err := o.Create(ctx, exec) + if err != nil { + tb.Fatal(err) + return nil + } + return m +} + +// CreateMany builds multiple publicreportPoolPhotos and inserts them into the database +// Relations objects are also inserted and placed in the .R field +func (o PublicreportPoolPhotoTemplate) CreateMany(ctx context.Context, exec bob.Executor, number int) (models.PublicreportPoolPhotoSlice, error) { + var err error + m := make(models.PublicreportPoolPhotoSlice, number) + + for i := range m { + m[i], err = o.Create(ctx, exec) + if err != nil { + return nil, err + } + } + + return m, nil +} + +// MustCreateMany builds multiple publicreportPoolPhotos and inserts them into the database +// Relations objects are also inserted and placed in the .R field +// panics if an error occurs +func (o PublicreportPoolPhotoTemplate) MustCreateMany(ctx context.Context, exec bob.Executor, number int) models.PublicreportPoolPhotoSlice { + m, err := o.CreateMany(ctx, exec, number) + if err != nil { + panic(err) + } + return m +} + +// CreateManyOrFail builds multiple publicreportPoolPhotos 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 PublicreportPoolPhotoTemplate) CreateManyOrFail(ctx context.Context, tb testing.TB, exec bob.Executor, number int) models.PublicreportPoolPhotoSlice { + tb.Helper() + m, err := o.CreateMany(ctx, exec, number) + if err != nil { + tb.Fatal(err) + return nil + } + return m +} + +// PublicreportPoolPhoto has methods that act as mods for the PublicreportPoolPhotoTemplate +var PublicreportPoolPhotoMods publicreportPoolPhotoMods + +type publicreportPoolPhotoMods struct{} + +func (m publicreportPoolPhotoMods) RandomizeAllColumns(f *faker.Faker) PublicreportPoolPhotoMod { + return PublicreportPoolPhotoModSlice{ + PublicreportPoolPhotoMods.RandomID(f), + PublicreportPoolPhotoMods.RandomSize(f), + PublicreportPoolPhotoMods.RandomFilename(f), + PublicreportPoolPhotoMods.RandomPoolID(f), + PublicreportPoolPhotoMods.RandomUUID(f), + } +} + +// Set the model columns to this value +func (m publicreportPoolPhotoMods) ID(val int32) PublicreportPoolPhotoMod { + return PublicreportPoolPhotoModFunc(func(_ context.Context, o *PublicreportPoolPhotoTemplate) { + o.ID = func() int32 { return val } + }) +} + +// Set the Column from the function +func (m publicreportPoolPhotoMods) IDFunc(f func() int32) PublicreportPoolPhotoMod { + return PublicreportPoolPhotoModFunc(func(_ context.Context, o *PublicreportPoolPhotoTemplate) { + o.ID = f + }) +} + +// Clear any values for the column +func (m publicreportPoolPhotoMods) UnsetID() PublicreportPoolPhotoMod { + return PublicreportPoolPhotoModFunc(func(_ context.Context, o *PublicreportPoolPhotoTemplate) { + o.ID = nil + }) +} + +// Generates a random value for the column using the given faker +// if faker is nil, a default faker is used +func (m publicreportPoolPhotoMods) RandomID(f *faker.Faker) PublicreportPoolPhotoMod { + return PublicreportPoolPhotoModFunc(func(_ context.Context, o *PublicreportPoolPhotoTemplate) { + o.ID = func() int32 { + return random_int32(f) + } + }) +} + +// Set the model columns to this value +func (m publicreportPoolPhotoMods) Size(val int64) PublicreportPoolPhotoMod { + return PublicreportPoolPhotoModFunc(func(_ context.Context, o *PublicreportPoolPhotoTemplate) { + o.Size = func() int64 { return val } + }) +} + +// Set the Column from the function +func (m publicreportPoolPhotoMods) SizeFunc(f func() int64) PublicreportPoolPhotoMod { + return PublicreportPoolPhotoModFunc(func(_ context.Context, o *PublicreportPoolPhotoTemplate) { + o.Size = f + }) +} + +// Clear any values for the column +func (m publicreportPoolPhotoMods) UnsetSize() PublicreportPoolPhotoMod { + return PublicreportPoolPhotoModFunc(func(_ context.Context, o *PublicreportPoolPhotoTemplate) { + o.Size = nil + }) +} + +// Generates a random value for the column using the given faker +// if faker is nil, a default faker is used +func (m publicreportPoolPhotoMods) RandomSize(f *faker.Faker) PublicreportPoolPhotoMod { + return PublicreportPoolPhotoModFunc(func(_ context.Context, o *PublicreportPoolPhotoTemplate) { + o.Size = func() int64 { + return random_int64(f) + } + }) +} + +// Set the model columns to this value +func (m publicreportPoolPhotoMods) Filename(val string) PublicreportPoolPhotoMod { + return PublicreportPoolPhotoModFunc(func(_ context.Context, o *PublicreportPoolPhotoTemplate) { + o.Filename = func() string { return val } + }) +} + +// Set the Column from the function +func (m publicreportPoolPhotoMods) FilenameFunc(f func() string) PublicreportPoolPhotoMod { + return PublicreportPoolPhotoModFunc(func(_ context.Context, o *PublicreportPoolPhotoTemplate) { + o.Filename = f + }) +} + +// Clear any values for the column +func (m publicreportPoolPhotoMods) UnsetFilename() PublicreportPoolPhotoMod { + return PublicreportPoolPhotoModFunc(func(_ context.Context, o *PublicreportPoolPhotoTemplate) { + o.Filename = nil + }) +} + +// Generates a random value for the column using the given faker +// if faker is nil, a default faker is used +func (m publicreportPoolPhotoMods) RandomFilename(f *faker.Faker) PublicreportPoolPhotoMod { + return PublicreportPoolPhotoModFunc(func(_ context.Context, o *PublicreportPoolPhotoTemplate) { + o.Filename = func() string { + return random_string(f) + } + }) +} + +// Set the model columns to this value +func (m publicreportPoolPhotoMods) PoolID(val int32) PublicreportPoolPhotoMod { + return PublicreportPoolPhotoModFunc(func(_ context.Context, o *PublicreportPoolPhotoTemplate) { + o.PoolID = func() int32 { return val } + }) +} + +// Set the Column from the function +func (m publicreportPoolPhotoMods) PoolIDFunc(f func() int32) PublicreportPoolPhotoMod { + return PublicreportPoolPhotoModFunc(func(_ context.Context, o *PublicreportPoolPhotoTemplate) { + o.PoolID = f + }) +} + +// Clear any values for the column +func (m publicreportPoolPhotoMods) UnsetPoolID() PublicreportPoolPhotoMod { + return PublicreportPoolPhotoModFunc(func(_ context.Context, o *PublicreportPoolPhotoTemplate) { + o.PoolID = nil + }) +} + +// Generates a random value for the column using the given faker +// if faker is nil, a default faker is used +func (m publicreportPoolPhotoMods) RandomPoolID(f *faker.Faker) PublicreportPoolPhotoMod { + return PublicreportPoolPhotoModFunc(func(_ context.Context, o *PublicreportPoolPhotoTemplate) { + o.PoolID = func() int32 { + return random_int32(f) + } + }) +} + +// Set the model columns to this value +func (m publicreportPoolPhotoMods) UUID(val uuid.UUID) PublicreportPoolPhotoMod { + return PublicreportPoolPhotoModFunc(func(_ context.Context, o *PublicreportPoolPhotoTemplate) { + o.UUID = func() uuid.UUID { return val } + }) +} + +// Set the Column from the function +func (m publicreportPoolPhotoMods) UUIDFunc(f func() uuid.UUID) PublicreportPoolPhotoMod { + return PublicreportPoolPhotoModFunc(func(_ context.Context, o *PublicreportPoolPhotoTemplate) { + o.UUID = f + }) +} + +// Clear any values for the column +func (m publicreportPoolPhotoMods) UnsetUUID() PublicreportPoolPhotoMod { + return PublicreportPoolPhotoModFunc(func(_ context.Context, o *PublicreportPoolPhotoTemplate) { + o.UUID = nil + }) +} + +// Generates a random value for the column using the given faker +// if faker is nil, a default faker is used +func (m publicreportPoolPhotoMods) RandomUUID(f *faker.Faker) PublicreportPoolPhotoMod { + return PublicreportPoolPhotoModFunc(func(_ context.Context, o *PublicreportPoolPhotoTemplate) { + o.UUID = func() uuid.UUID { + return random_uuid_UUID(f) + } + }) +} + +func (m publicreportPoolPhotoMods) WithParentsCascading() PublicreportPoolPhotoMod { + return PublicreportPoolPhotoModFunc(func(ctx context.Context, o *PublicreportPoolPhotoTemplate) { + if isDone, _ := publicreportPoolPhotoWithParentsCascadingCtx.Value(ctx); isDone { + return + } + ctx = publicreportPoolPhotoWithParentsCascadingCtx.WithValue(ctx, true) + { + + related := o.f.NewPublicreportPoolWithContext(ctx, PublicreportPoolMods.WithParentsCascading()) + m.WithPool(related).Apply(ctx, o) + } + }) +} + +func (m publicreportPoolPhotoMods) WithPool(rel *PublicreportPoolTemplate) PublicreportPoolPhotoMod { + return PublicreportPoolPhotoModFunc(func(ctx context.Context, o *PublicreportPoolPhotoTemplate) { + o.r.Pool = &publicreportPoolPhotoRPoolR{ + o: rel, + } + }) +} + +func (m publicreportPoolPhotoMods) WithNewPool(mods ...PublicreportPoolMod) PublicreportPoolPhotoMod { + return PublicreportPoolPhotoModFunc(func(ctx context.Context, o *PublicreportPoolPhotoTemplate) { + related := o.f.NewPublicreportPoolWithContext(ctx, mods...) + + m.WithPool(related).Apply(ctx, o) + }) +} + +func (m publicreportPoolPhotoMods) WithExistingPool(em *models.PublicreportPool) PublicreportPoolPhotoMod { + return PublicreportPoolPhotoModFunc(func(ctx context.Context, o *PublicreportPoolPhotoTemplate) { + o.r.Pool = &publicreportPoolPhotoRPoolR{ + o: o.f.FromExistingPublicreportPool(em), + } + }) +} + +func (m publicreportPoolPhotoMods) WithoutPool() PublicreportPoolPhotoMod { + return PublicreportPoolPhotoModFunc(func(ctx context.Context, o *PublicreportPoolPhotoTemplate) { + o.r.Pool = nil + }) +} diff --git a/db/migrations/00024_public_report.sql b/db/migrations/00024_publicreport_quick.sql similarity index 100% rename from db/migrations/00024_public_report.sql rename to db/migrations/00024_publicreport_quick.sql diff --git a/db/migrations/00025_public_nuisance.sql b/db/migrations/00025_publicreport_nuisance.sql similarity index 100% rename from db/migrations/00025_public_nuisance.sql rename to db/migrations/00025_publicreport_nuisance.sql diff --git a/db/migrations/00026_publicreport_pool.sql b/db/migrations/00026_publicreport_pool.sql new file mode 100644 index 00000000..b32fab4d --- /dev/null +++ b/db/migrations/00026_publicreport_pool.sql @@ -0,0 +1,53 @@ +-- +goose Up +CREATE TYPE publicreport.PoolSourceDuration AS ENUM ( + 'none', + 'less-than-week', + '1-2-weeks', + '2-4-weeks', + '1-3-months', + 'more-than-3-months' +); +CREATE TABLE publicreport.pool ( + id SERIAL PRIMARY KEY, + access_comments TEXT NOT NULL, + access_gate BOOLEAN NOT NULL, + access_fence BOOLEAN NOT NULL, + access_locked BOOLEAN NOT NULL, + access_dog BOOLEAN NOT NULL, + access_other BOOLEAN NOT NULL, + address TEXT NOT NULL, + address_country TEXT NOT NULL, + address_post_code TEXT NOT NULL, + address_place TEXT NOT NULL, + address_street TEXT NOT NULL, + address_region TEXT NOT NULL, + comments TEXT NOT NULL, + created TIMESTAMP WITHOUT TIME ZONE NOT NULL, + h3cell h3index, + has_adult BOOLEAN NOT NULL, + has_larvae BOOLEAN NOT NULL, + has_pupae BOOLEAN NOT NULL, + location GEOGRAPHY, + map_zoom FLOAT NOT NULL, + owner_email TEXT NOT NULL, + owner_name TEXT NOT NULL, + owner_phone TEXT NOT NULL, + public_id TEXT NOT NULL UNIQUE, + reporter_email TEXT NOT NULL, + reporter_name TEXT NOT NULL, + reporter_phone TEXT NOT NULL, + subscribe BOOLEAN NOT NULL +); + +CREATE TABLE publicreport.pool_photo ( + id SERIAL PRIMARY KEY, + size BIGINT NOT NULL, + filename TEXT NOT NULL, + pool_id INT NOT NULL REFERENCES publicreport.pool(id), + uuid UUID NOT NULL +); + +-- +goose Down +DROP TABLE publicreport.pool_photo; +DROP TABLE publicreport.pool; +DROP TYPE publicreport.PoolSourceDuration; diff --git a/db/models/bob_joins.bob.go b/db/models/bob_joins.bob.go index 6965dcd3..37643b0c 100644 --- a/db/models/bob_joins.bob.go +++ b/db/models/bob_joins.bob.go @@ -70,6 +70,8 @@ type joins[Q dialect.Joinable] struct { Notifications joinSet[notificationJoins[Q]] OauthTokens joinSet[oauthTokenJoins[Q]] Organizations joinSet[organizationJoins[Q]] + PublicreportPools joinSet[publicreportPoolJoins[Q]] + PublicreportPoolPhotos joinSet[publicreportPoolPhotoJoins[Q]] PublicreportQuicks joinSet[publicreportQuickJoins[Q]] PublicreportQuickPhotos joinSet[publicreportQuickPhotoJoins[Q]] Users joinSet[userJoins[Q]] @@ -123,6 +125,8 @@ func getJoins[Q dialect.Joinable]() joins[Q] { Notifications: buildJoinSet[notificationJoins[Q]](Notifications.Columns, buildNotificationJoins), OauthTokens: buildJoinSet[oauthTokenJoins[Q]](OauthTokens.Columns, buildOauthTokenJoins), Organizations: buildJoinSet[organizationJoins[Q]](Organizations.Columns, buildOrganizationJoins), + PublicreportPools: buildJoinSet[publicreportPoolJoins[Q]](PublicreportPools.Columns, buildPublicreportPoolJoins), + PublicreportPoolPhotos: buildJoinSet[publicreportPoolPhotoJoins[Q]](PublicreportPoolPhotos.Columns, buildPublicreportPoolPhotoJoins), PublicreportQuicks: buildJoinSet[publicreportQuickJoins[Q]](PublicreportQuicks.Columns, buildPublicreportQuickJoins), PublicreportQuickPhotos: buildJoinSet[publicreportQuickPhotoJoins[Q]](PublicreportQuickPhotos.Columns, buildPublicreportQuickPhotoJoins), Users: buildJoinSet[userJoins[Q]](Users.Columns, buildUserJoins), diff --git a/db/models/bob_loaders.bob.go b/db/models/bob_loaders.bob.go index 98764377..5af29980 100644 --- a/db/models/bob_loaders.bob.go +++ b/db/models/bob_loaders.bob.go @@ -55,6 +55,8 @@ type preloaders struct { Notification notificationPreloader OauthToken oauthTokenPreloader Organization organizationPreloader + PublicreportPool publicreportPoolPreloader + PublicreportPoolPhoto publicreportPoolPhotoPreloader PublicreportQuick publicreportQuickPreloader PublicreportQuickPhoto publicreportQuickPhotoPreloader User userPreloader @@ -100,6 +102,8 @@ func getPreloaders() preloaders { Notification: buildNotificationPreloader(), OauthToken: buildOauthTokenPreloader(), Organization: buildOrganizationPreloader(), + PublicreportPool: buildPublicreportPoolPreloader(), + PublicreportPoolPhoto: buildPublicreportPoolPhotoPreloader(), PublicreportQuick: buildPublicreportQuickPreloader(), PublicreportQuickPhoto: buildPublicreportQuickPhotoPreloader(), User: buildUserPreloader(), @@ -151,6 +155,8 @@ type thenLoaders[Q orm.Loadable] struct { Notification notificationThenLoader[Q] OauthToken oauthTokenThenLoader[Q] Organization organizationThenLoader[Q] + PublicreportPool publicreportPoolThenLoader[Q] + PublicreportPoolPhoto publicreportPoolPhotoThenLoader[Q] PublicreportQuick publicreportQuickThenLoader[Q] PublicreportQuickPhoto publicreportQuickPhotoThenLoader[Q] User userThenLoader[Q] @@ -196,6 +202,8 @@ func getThenLoaders[Q orm.Loadable]() thenLoaders[Q] { Notification: buildNotificationThenLoader[Q](), OauthToken: buildOauthTokenThenLoader[Q](), Organization: buildOrganizationThenLoader[Q](), + PublicreportPool: buildPublicreportPoolThenLoader[Q](), + PublicreportPoolPhoto: buildPublicreportPoolPhotoThenLoader[Q](), PublicreportQuick: buildPublicreportQuickThenLoader[Q](), PublicreportQuickPhoto: buildPublicreportQuickPhotoThenLoader[Q](), User: buildUserThenLoader[Q](), diff --git a/db/models/bob_where.bob.go b/db/models/bob_where.bob.go index fb639108..cfb5ef12 100644 --- a/db/models/bob_where.bob.go +++ b/db/models/bob_where.bob.go @@ -59,6 +59,8 @@ func Where[Q psql.Filterable]() struct { OauthTokens oauthTokenWhere[Q] Organizations organizationWhere[Q] PublicreportNuisances publicreportNuisanceWhere[Q] + PublicreportPools publicreportPoolWhere[Q] + PublicreportPoolPhotos publicreportPoolPhotoWhere[Q] PublicreportQuicks publicreportQuickWhere[Q] PublicreportQuickPhotos publicreportQuickPhotoWhere[Q] RasterColumns rasterColumnWhere[Q] @@ -110,6 +112,8 @@ func Where[Q psql.Filterable]() struct { OauthTokens oauthTokenWhere[Q] Organizations organizationWhere[Q] PublicreportNuisances publicreportNuisanceWhere[Q] + PublicreportPools publicreportPoolWhere[Q] + PublicreportPoolPhotos publicreportPoolPhotoWhere[Q] PublicreportQuicks publicreportQuickWhere[Q] PublicreportQuickPhotos publicreportQuickPhotoWhere[Q] RasterColumns rasterColumnWhere[Q] @@ -160,6 +164,8 @@ func Where[Q psql.Filterable]() struct { OauthTokens: buildOauthTokenWhere[Q](OauthTokens.Columns), Organizations: buildOrganizationWhere[Q](Organizations.Columns), PublicreportNuisances: buildPublicreportNuisanceWhere[Q](PublicreportNuisances.Columns), + PublicreportPools: buildPublicreportPoolWhere[Q](PublicreportPools.Columns), + PublicreportPoolPhotos: buildPublicreportPoolPhotoWhere[Q](PublicreportPoolPhotos.Columns), PublicreportQuicks: buildPublicreportQuickWhere[Q](PublicreportQuicks.Columns), PublicreportQuickPhotos: buildPublicreportQuickPhotoWhere[Q](PublicreportQuickPhotos.Columns), RasterColumns: buildRasterColumnWhere[Q](RasterColumns.Columns), diff --git a/db/models/publicreport.pool.bob.go b/db/models/publicreport.pool.bob.go new file mode 100644 index 00000000..2569a101 --- /dev/null +++ b/db/models/publicreport.pool.bob.go @@ -0,0 +1,1295 @@ +// Code generated by BobGen psql v0.0.4-0.20260105020634-53e08d840e47+dirty. DO NOT EDIT. +// This file is meant to be re-generated in place and/or deleted at any time. + +package models + +import ( + "context" + "fmt" + "io" + "time" + + "github.com/aarondl/opt/null" + "github.com/aarondl/opt/omit" + "github.com/aarondl/opt/omitnull" + "github.com/stephenafamo/bob" + "github.com/stephenafamo/bob/dialect/psql" + "github.com/stephenafamo/bob/dialect/psql/dialect" + "github.com/stephenafamo/bob/dialect/psql/dm" + "github.com/stephenafamo/bob/dialect/psql/sm" + "github.com/stephenafamo/bob/dialect/psql/um" + "github.com/stephenafamo/bob/expr" + "github.com/stephenafamo/bob/mods" + "github.com/stephenafamo/bob/orm" + "github.com/stephenafamo/bob/types/pgtypes" +) + +// PublicreportPool is an object representing the database table. +type PublicreportPool struct { + ID int32 `db:"id,pk" ` + AccessComments string `db:"access_comments" ` + AccessGate bool `db:"access_gate" ` + AccessFence bool `db:"access_fence" ` + AccessLocked bool `db:"access_locked" ` + AccessDog bool `db:"access_dog" ` + AccessOther bool `db:"access_other" ` + Address string `db:"address" ` + AddressCountry string `db:"address_country" ` + AddressPostCode string `db:"address_post_code" ` + AddressPlace string `db:"address_place" ` + AddressStreet string `db:"address_street" ` + AddressRegion string `db:"address_region" ` + Comments string `db:"comments" ` + Created time.Time `db:"created" ` + H3cell null.Val[string] `db:"h3cell" ` + HasAdult bool `db:"has_adult" ` + HasLarvae bool `db:"has_larvae" ` + HasPupae bool `db:"has_pupae" ` + Location null.Val[string] `db:"location" ` + MapZoom float64 `db:"map_zoom" ` + OwnerEmail string `db:"owner_email" ` + OwnerName string `db:"owner_name" ` + OwnerPhone string `db:"owner_phone" ` + PublicID string `db:"public_id" ` + ReporterEmail string `db:"reporter_email" ` + ReporterName string `db:"reporter_name" ` + ReporterPhone string `db:"reporter_phone" ` + Subscribe bool `db:"subscribe" ` + + R publicreportPoolR `db:"-" ` +} + +// PublicreportPoolSlice is an alias for a slice of pointers to PublicreportPool. +// This should almost always be used instead of []*PublicreportPool. +type PublicreportPoolSlice []*PublicreportPool + +// PublicreportPools contains methods to work with the pool table +var PublicreportPools = psql.NewTablex[*PublicreportPool, PublicreportPoolSlice, *PublicreportPoolSetter]("publicreport", "pool", buildPublicreportPoolColumns("publicreport.pool")) + +// PublicreportPoolsQuery is a query on the pool table +type PublicreportPoolsQuery = *psql.ViewQuery[*PublicreportPool, PublicreportPoolSlice] + +// publicreportPoolR is where relationships are stored. +type publicreportPoolR struct { + PoolPhotos PublicreportPoolPhotoSlice // publicreport.pool_photo.pool_photo_pool_id_fkey +} + +func buildPublicreportPoolColumns(alias string) publicreportPoolColumns { + return publicreportPoolColumns{ + ColumnsExpr: expr.NewColumnsExpr( + "id", "access_comments", "access_gate", "access_fence", "access_locked", "access_dog", "access_other", "address", "address_country", "address_post_code", "address_place", "address_street", "address_region", "comments", "created", "h3cell", "has_adult", "has_larvae", "has_pupae", "location", "map_zoom", "owner_email", "owner_name", "owner_phone", "public_id", "reporter_email", "reporter_name", "reporter_phone", "subscribe", + ).WithParent("publicreport.pool"), + tableAlias: alias, + ID: psql.Quote(alias, "id"), + AccessComments: psql.Quote(alias, "access_comments"), + AccessGate: psql.Quote(alias, "access_gate"), + AccessFence: psql.Quote(alias, "access_fence"), + AccessLocked: psql.Quote(alias, "access_locked"), + AccessDog: psql.Quote(alias, "access_dog"), + AccessOther: psql.Quote(alias, "access_other"), + Address: psql.Quote(alias, "address"), + AddressCountry: psql.Quote(alias, "address_country"), + AddressPostCode: psql.Quote(alias, "address_post_code"), + AddressPlace: psql.Quote(alias, "address_place"), + AddressStreet: psql.Quote(alias, "address_street"), + AddressRegion: psql.Quote(alias, "address_region"), + Comments: psql.Quote(alias, "comments"), + Created: psql.Quote(alias, "created"), + H3cell: psql.Quote(alias, "h3cell"), + HasAdult: psql.Quote(alias, "has_adult"), + HasLarvae: psql.Quote(alias, "has_larvae"), + HasPupae: psql.Quote(alias, "has_pupae"), + Location: psql.Quote(alias, "location"), + MapZoom: psql.Quote(alias, "map_zoom"), + OwnerEmail: psql.Quote(alias, "owner_email"), + OwnerName: psql.Quote(alias, "owner_name"), + OwnerPhone: psql.Quote(alias, "owner_phone"), + PublicID: psql.Quote(alias, "public_id"), + ReporterEmail: psql.Quote(alias, "reporter_email"), + ReporterName: psql.Quote(alias, "reporter_name"), + ReporterPhone: psql.Quote(alias, "reporter_phone"), + Subscribe: psql.Quote(alias, "subscribe"), + } +} + +type publicreportPoolColumns struct { + expr.ColumnsExpr + tableAlias string + ID psql.Expression + AccessComments psql.Expression + AccessGate psql.Expression + AccessFence psql.Expression + AccessLocked psql.Expression + AccessDog psql.Expression + AccessOther psql.Expression + Address psql.Expression + AddressCountry psql.Expression + AddressPostCode psql.Expression + AddressPlace psql.Expression + AddressStreet psql.Expression + AddressRegion psql.Expression + Comments psql.Expression + Created psql.Expression + H3cell psql.Expression + HasAdult psql.Expression + HasLarvae psql.Expression + HasPupae psql.Expression + Location psql.Expression + MapZoom psql.Expression + OwnerEmail psql.Expression + OwnerName psql.Expression + OwnerPhone psql.Expression + PublicID psql.Expression + ReporterEmail psql.Expression + ReporterName psql.Expression + ReporterPhone psql.Expression + Subscribe psql.Expression +} + +func (c publicreportPoolColumns) Alias() string { + return c.tableAlias +} + +func (publicreportPoolColumns) AliasedAs(alias string) publicreportPoolColumns { + return buildPublicreportPoolColumns(alias) +} + +// PublicreportPoolSetter is used for insert/upsert/update operations +// All values are optional, and do not have to be set +// Generated columns are not included +type PublicreportPoolSetter struct { + ID omit.Val[int32] `db:"id,pk" ` + AccessComments omit.Val[string] `db:"access_comments" ` + AccessGate omit.Val[bool] `db:"access_gate" ` + AccessFence omit.Val[bool] `db:"access_fence" ` + AccessLocked omit.Val[bool] `db:"access_locked" ` + AccessDog omit.Val[bool] `db:"access_dog" ` + AccessOther omit.Val[bool] `db:"access_other" ` + Address omit.Val[string] `db:"address" ` + AddressCountry omit.Val[string] `db:"address_country" ` + AddressPostCode omit.Val[string] `db:"address_post_code" ` + AddressPlace omit.Val[string] `db:"address_place" ` + AddressStreet omit.Val[string] `db:"address_street" ` + AddressRegion omit.Val[string] `db:"address_region" ` + Comments omit.Val[string] `db:"comments" ` + Created omit.Val[time.Time] `db:"created" ` + H3cell omitnull.Val[string] `db:"h3cell" ` + HasAdult omit.Val[bool] `db:"has_adult" ` + HasLarvae omit.Val[bool] `db:"has_larvae" ` + HasPupae omit.Val[bool] `db:"has_pupae" ` + Location omitnull.Val[string] `db:"location" ` + MapZoom omit.Val[float64] `db:"map_zoom" ` + OwnerEmail omit.Val[string] `db:"owner_email" ` + OwnerName omit.Val[string] `db:"owner_name" ` + OwnerPhone omit.Val[string] `db:"owner_phone" ` + PublicID omit.Val[string] `db:"public_id" ` + ReporterEmail omit.Val[string] `db:"reporter_email" ` + ReporterName omit.Val[string] `db:"reporter_name" ` + ReporterPhone omit.Val[string] `db:"reporter_phone" ` + Subscribe omit.Val[bool] `db:"subscribe" ` +} + +func (s PublicreportPoolSetter) SetColumns() []string { + vals := make([]string, 0, 29) + if s.ID.IsValue() { + vals = append(vals, "id") + } + if s.AccessComments.IsValue() { + vals = append(vals, "access_comments") + } + if s.AccessGate.IsValue() { + vals = append(vals, "access_gate") + } + if s.AccessFence.IsValue() { + vals = append(vals, "access_fence") + } + if s.AccessLocked.IsValue() { + vals = append(vals, "access_locked") + } + if s.AccessDog.IsValue() { + vals = append(vals, "access_dog") + } + if s.AccessOther.IsValue() { + vals = append(vals, "access_other") + } + if s.Address.IsValue() { + vals = append(vals, "address") + } + if s.AddressCountry.IsValue() { + vals = append(vals, "address_country") + } + if s.AddressPostCode.IsValue() { + vals = append(vals, "address_post_code") + } + if s.AddressPlace.IsValue() { + vals = append(vals, "address_place") + } + if s.AddressStreet.IsValue() { + vals = append(vals, "address_street") + } + if s.AddressRegion.IsValue() { + vals = append(vals, "address_region") + } + if s.Comments.IsValue() { + vals = append(vals, "comments") + } + if s.Created.IsValue() { + vals = append(vals, "created") + } + if !s.H3cell.IsUnset() { + vals = append(vals, "h3cell") + } + if s.HasAdult.IsValue() { + vals = append(vals, "has_adult") + } + if s.HasLarvae.IsValue() { + vals = append(vals, "has_larvae") + } + if s.HasPupae.IsValue() { + vals = append(vals, "has_pupae") + } + if !s.Location.IsUnset() { + vals = append(vals, "location") + } + if s.MapZoom.IsValue() { + vals = append(vals, "map_zoom") + } + if s.OwnerEmail.IsValue() { + vals = append(vals, "owner_email") + } + if s.OwnerName.IsValue() { + vals = append(vals, "owner_name") + } + if s.OwnerPhone.IsValue() { + vals = append(vals, "owner_phone") + } + if s.PublicID.IsValue() { + vals = append(vals, "public_id") + } + if s.ReporterEmail.IsValue() { + vals = append(vals, "reporter_email") + } + if s.ReporterName.IsValue() { + vals = append(vals, "reporter_name") + } + if s.ReporterPhone.IsValue() { + vals = append(vals, "reporter_phone") + } + if s.Subscribe.IsValue() { + vals = append(vals, "subscribe") + } + return vals +} + +func (s PublicreportPoolSetter) Overwrite(t *PublicreportPool) { + if s.ID.IsValue() { + t.ID = s.ID.MustGet() + } + if s.AccessComments.IsValue() { + t.AccessComments = s.AccessComments.MustGet() + } + if s.AccessGate.IsValue() { + t.AccessGate = s.AccessGate.MustGet() + } + if s.AccessFence.IsValue() { + t.AccessFence = s.AccessFence.MustGet() + } + if s.AccessLocked.IsValue() { + t.AccessLocked = s.AccessLocked.MustGet() + } + if s.AccessDog.IsValue() { + t.AccessDog = s.AccessDog.MustGet() + } + if s.AccessOther.IsValue() { + t.AccessOther = s.AccessOther.MustGet() + } + if s.Address.IsValue() { + t.Address = s.Address.MustGet() + } + if s.AddressCountry.IsValue() { + t.AddressCountry = s.AddressCountry.MustGet() + } + if s.AddressPostCode.IsValue() { + t.AddressPostCode = s.AddressPostCode.MustGet() + } + if s.AddressPlace.IsValue() { + t.AddressPlace = s.AddressPlace.MustGet() + } + if s.AddressStreet.IsValue() { + t.AddressStreet = s.AddressStreet.MustGet() + } + if s.AddressRegion.IsValue() { + t.AddressRegion = s.AddressRegion.MustGet() + } + if s.Comments.IsValue() { + t.Comments = s.Comments.MustGet() + } + if s.Created.IsValue() { + t.Created = s.Created.MustGet() + } + if !s.H3cell.IsUnset() { + t.H3cell = s.H3cell.MustGetNull() + } + if s.HasAdult.IsValue() { + t.HasAdult = s.HasAdult.MustGet() + } + if s.HasLarvae.IsValue() { + t.HasLarvae = s.HasLarvae.MustGet() + } + if s.HasPupae.IsValue() { + t.HasPupae = s.HasPupae.MustGet() + } + if !s.Location.IsUnset() { + t.Location = s.Location.MustGetNull() + } + if s.MapZoom.IsValue() { + t.MapZoom = s.MapZoom.MustGet() + } + if s.OwnerEmail.IsValue() { + t.OwnerEmail = s.OwnerEmail.MustGet() + } + if s.OwnerName.IsValue() { + t.OwnerName = s.OwnerName.MustGet() + } + if s.OwnerPhone.IsValue() { + t.OwnerPhone = s.OwnerPhone.MustGet() + } + if s.PublicID.IsValue() { + t.PublicID = s.PublicID.MustGet() + } + if s.ReporterEmail.IsValue() { + t.ReporterEmail = s.ReporterEmail.MustGet() + } + if s.ReporterName.IsValue() { + t.ReporterName = s.ReporterName.MustGet() + } + if s.ReporterPhone.IsValue() { + t.ReporterPhone = s.ReporterPhone.MustGet() + } + if s.Subscribe.IsValue() { + t.Subscribe = s.Subscribe.MustGet() + } +} + +func (s *PublicreportPoolSetter) Apply(q *dialect.InsertQuery) { + q.AppendHooks(func(ctx context.Context, exec bob.Executor) (context.Context, error) { + return PublicreportPools.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, 29) + if s.ID.IsValue() { + vals[0] = psql.Arg(s.ID.MustGet()) + } else { + vals[0] = psql.Raw("DEFAULT") + } + + if s.AccessComments.IsValue() { + vals[1] = psql.Arg(s.AccessComments.MustGet()) + } else { + vals[1] = psql.Raw("DEFAULT") + } + + if s.AccessGate.IsValue() { + vals[2] = psql.Arg(s.AccessGate.MustGet()) + } else { + vals[2] = psql.Raw("DEFAULT") + } + + if s.AccessFence.IsValue() { + vals[3] = psql.Arg(s.AccessFence.MustGet()) + } else { + vals[3] = psql.Raw("DEFAULT") + } + + if s.AccessLocked.IsValue() { + vals[4] = psql.Arg(s.AccessLocked.MustGet()) + } else { + vals[4] = psql.Raw("DEFAULT") + } + + if s.AccessDog.IsValue() { + vals[5] = psql.Arg(s.AccessDog.MustGet()) + } else { + vals[5] = psql.Raw("DEFAULT") + } + + if s.AccessOther.IsValue() { + vals[6] = psql.Arg(s.AccessOther.MustGet()) + } else { + vals[6] = psql.Raw("DEFAULT") + } + + if s.Address.IsValue() { + vals[7] = psql.Arg(s.Address.MustGet()) + } else { + vals[7] = psql.Raw("DEFAULT") + } + + if s.AddressCountry.IsValue() { + vals[8] = psql.Arg(s.AddressCountry.MustGet()) + } else { + vals[8] = psql.Raw("DEFAULT") + } + + if s.AddressPostCode.IsValue() { + vals[9] = psql.Arg(s.AddressPostCode.MustGet()) + } else { + vals[9] = psql.Raw("DEFAULT") + } + + if s.AddressPlace.IsValue() { + vals[10] = psql.Arg(s.AddressPlace.MustGet()) + } else { + vals[10] = psql.Raw("DEFAULT") + } + + if s.AddressStreet.IsValue() { + vals[11] = psql.Arg(s.AddressStreet.MustGet()) + } else { + vals[11] = psql.Raw("DEFAULT") + } + + if s.AddressRegion.IsValue() { + vals[12] = psql.Arg(s.AddressRegion.MustGet()) + } else { + vals[12] = psql.Raw("DEFAULT") + } + + if s.Comments.IsValue() { + vals[13] = psql.Arg(s.Comments.MustGet()) + } else { + vals[13] = psql.Raw("DEFAULT") + } + + if s.Created.IsValue() { + vals[14] = psql.Arg(s.Created.MustGet()) + } else { + vals[14] = psql.Raw("DEFAULT") + } + + if !s.H3cell.IsUnset() { + vals[15] = psql.Arg(s.H3cell.MustGetNull()) + } else { + vals[15] = psql.Raw("DEFAULT") + } + + if s.HasAdult.IsValue() { + vals[16] = psql.Arg(s.HasAdult.MustGet()) + } else { + vals[16] = psql.Raw("DEFAULT") + } + + if s.HasLarvae.IsValue() { + vals[17] = psql.Arg(s.HasLarvae.MustGet()) + } else { + vals[17] = psql.Raw("DEFAULT") + } + + if s.HasPupae.IsValue() { + vals[18] = psql.Arg(s.HasPupae.MustGet()) + } else { + vals[18] = psql.Raw("DEFAULT") + } + + if !s.Location.IsUnset() { + vals[19] = psql.Arg(s.Location.MustGetNull()) + } else { + vals[19] = psql.Raw("DEFAULT") + } + + if s.MapZoom.IsValue() { + vals[20] = psql.Arg(s.MapZoom.MustGet()) + } else { + vals[20] = psql.Raw("DEFAULT") + } + + if s.OwnerEmail.IsValue() { + vals[21] = psql.Arg(s.OwnerEmail.MustGet()) + } else { + vals[21] = psql.Raw("DEFAULT") + } + + if s.OwnerName.IsValue() { + vals[22] = psql.Arg(s.OwnerName.MustGet()) + } else { + vals[22] = psql.Raw("DEFAULT") + } + + if s.OwnerPhone.IsValue() { + vals[23] = psql.Arg(s.OwnerPhone.MustGet()) + } else { + vals[23] = psql.Raw("DEFAULT") + } + + if s.PublicID.IsValue() { + vals[24] = psql.Arg(s.PublicID.MustGet()) + } else { + vals[24] = psql.Raw("DEFAULT") + } + + if s.ReporterEmail.IsValue() { + vals[25] = psql.Arg(s.ReporterEmail.MustGet()) + } else { + vals[25] = psql.Raw("DEFAULT") + } + + if s.ReporterName.IsValue() { + vals[26] = psql.Arg(s.ReporterName.MustGet()) + } else { + vals[26] = psql.Raw("DEFAULT") + } + + if s.ReporterPhone.IsValue() { + vals[27] = psql.Arg(s.ReporterPhone.MustGet()) + } else { + vals[27] = psql.Raw("DEFAULT") + } + + if s.Subscribe.IsValue() { + vals[28] = psql.Arg(s.Subscribe.MustGet()) + } else { + vals[28] = psql.Raw("DEFAULT") + } + + return bob.ExpressSlice(ctx, w, d, start, vals, "", ", ", "") + })) +} + +func (s PublicreportPoolSetter) UpdateMod() bob.Mod[*dialect.UpdateQuery] { + return um.Set(s.Expressions()...) +} + +func (s PublicreportPoolSetter) Expressions(prefix ...string) []bob.Expression { + exprs := make([]bob.Expression, 0, 29) + + if s.ID.IsValue() { + exprs = append(exprs, expr.Join{Sep: " = ", Exprs: []bob.Expression{ + psql.Quote(append(prefix, "id")...), + psql.Arg(s.ID), + }}) + } + + if s.AccessComments.IsValue() { + exprs = append(exprs, expr.Join{Sep: " = ", Exprs: []bob.Expression{ + psql.Quote(append(prefix, "access_comments")...), + psql.Arg(s.AccessComments), + }}) + } + + if s.AccessGate.IsValue() { + exprs = append(exprs, expr.Join{Sep: " = ", Exprs: []bob.Expression{ + psql.Quote(append(prefix, "access_gate")...), + psql.Arg(s.AccessGate), + }}) + } + + if s.AccessFence.IsValue() { + exprs = append(exprs, expr.Join{Sep: " = ", Exprs: []bob.Expression{ + psql.Quote(append(prefix, "access_fence")...), + psql.Arg(s.AccessFence), + }}) + } + + if s.AccessLocked.IsValue() { + exprs = append(exprs, expr.Join{Sep: " = ", Exprs: []bob.Expression{ + psql.Quote(append(prefix, "access_locked")...), + psql.Arg(s.AccessLocked), + }}) + } + + if s.AccessDog.IsValue() { + exprs = append(exprs, expr.Join{Sep: " = ", Exprs: []bob.Expression{ + psql.Quote(append(prefix, "access_dog")...), + psql.Arg(s.AccessDog), + }}) + } + + if s.AccessOther.IsValue() { + exprs = append(exprs, expr.Join{Sep: " = ", Exprs: []bob.Expression{ + psql.Quote(append(prefix, "access_other")...), + psql.Arg(s.AccessOther), + }}) + } + + if s.Address.IsValue() { + exprs = append(exprs, expr.Join{Sep: " = ", Exprs: []bob.Expression{ + psql.Quote(append(prefix, "address")...), + psql.Arg(s.Address), + }}) + } + + if s.AddressCountry.IsValue() { + exprs = append(exprs, expr.Join{Sep: " = ", Exprs: []bob.Expression{ + psql.Quote(append(prefix, "address_country")...), + psql.Arg(s.AddressCountry), + }}) + } + + if s.AddressPostCode.IsValue() { + exprs = append(exprs, expr.Join{Sep: " = ", Exprs: []bob.Expression{ + psql.Quote(append(prefix, "address_post_code")...), + psql.Arg(s.AddressPostCode), + }}) + } + + if s.AddressPlace.IsValue() { + exprs = append(exprs, expr.Join{Sep: " = ", Exprs: []bob.Expression{ + psql.Quote(append(prefix, "address_place")...), + psql.Arg(s.AddressPlace), + }}) + } + + if s.AddressStreet.IsValue() { + exprs = append(exprs, expr.Join{Sep: " = ", Exprs: []bob.Expression{ + psql.Quote(append(prefix, "address_street")...), + psql.Arg(s.AddressStreet), + }}) + } + + if s.AddressRegion.IsValue() { + exprs = append(exprs, expr.Join{Sep: " = ", Exprs: []bob.Expression{ + psql.Quote(append(prefix, "address_region")...), + psql.Arg(s.AddressRegion), + }}) + } + + if s.Comments.IsValue() { + exprs = append(exprs, expr.Join{Sep: " = ", Exprs: []bob.Expression{ + psql.Quote(append(prefix, "comments")...), + psql.Arg(s.Comments), + }}) + } + + if s.Created.IsValue() { + exprs = append(exprs, expr.Join{Sep: " = ", Exprs: []bob.Expression{ + psql.Quote(append(prefix, "created")...), + psql.Arg(s.Created), + }}) + } + + if !s.H3cell.IsUnset() { + exprs = append(exprs, expr.Join{Sep: " = ", Exprs: []bob.Expression{ + psql.Quote(append(prefix, "h3cell")...), + psql.Arg(s.H3cell), + }}) + } + + if s.HasAdult.IsValue() { + exprs = append(exprs, expr.Join{Sep: " = ", Exprs: []bob.Expression{ + psql.Quote(append(prefix, "has_adult")...), + psql.Arg(s.HasAdult), + }}) + } + + if s.HasLarvae.IsValue() { + exprs = append(exprs, expr.Join{Sep: " = ", Exprs: []bob.Expression{ + psql.Quote(append(prefix, "has_larvae")...), + psql.Arg(s.HasLarvae), + }}) + } + + if s.HasPupae.IsValue() { + exprs = append(exprs, expr.Join{Sep: " = ", Exprs: []bob.Expression{ + psql.Quote(append(prefix, "has_pupae")...), + psql.Arg(s.HasPupae), + }}) + } + + if !s.Location.IsUnset() { + exprs = append(exprs, expr.Join{Sep: " = ", Exprs: []bob.Expression{ + psql.Quote(append(prefix, "location")...), + psql.Arg(s.Location), + }}) + } + + if s.MapZoom.IsValue() { + exprs = append(exprs, expr.Join{Sep: " = ", Exprs: []bob.Expression{ + psql.Quote(append(prefix, "map_zoom")...), + psql.Arg(s.MapZoom), + }}) + } + + if s.OwnerEmail.IsValue() { + exprs = append(exprs, expr.Join{Sep: " = ", Exprs: []bob.Expression{ + psql.Quote(append(prefix, "owner_email")...), + psql.Arg(s.OwnerEmail), + }}) + } + + if s.OwnerName.IsValue() { + exprs = append(exprs, expr.Join{Sep: " = ", Exprs: []bob.Expression{ + psql.Quote(append(prefix, "owner_name")...), + psql.Arg(s.OwnerName), + }}) + } + + if s.OwnerPhone.IsValue() { + exprs = append(exprs, expr.Join{Sep: " = ", Exprs: []bob.Expression{ + psql.Quote(append(prefix, "owner_phone")...), + psql.Arg(s.OwnerPhone), + }}) + } + + if s.PublicID.IsValue() { + exprs = append(exprs, expr.Join{Sep: " = ", Exprs: []bob.Expression{ + psql.Quote(append(prefix, "public_id")...), + psql.Arg(s.PublicID), + }}) + } + + if s.ReporterEmail.IsValue() { + exprs = append(exprs, expr.Join{Sep: " = ", Exprs: []bob.Expression{ + psql.Quote(append(prefix, "reporter_email")...), + psql.Arg(s.ReporterEmail), + }}) + } + + if s.ReporterName.IsValue() { + exprs = append(exprs, expr.Join{Sep: " = ", Exprs: []bob.Expression{ + psql.Quote(append(prefix, "reporter_name")...), + psql.Arg(s.ReporterName), + }}) + } + + if s.ReporterPhone.IsValue() { + exprs = append(exprs, expr.Join{Sep: " = ", Exprs: []bob.Expression{ + psql.Quote(append(prefix, "reporter_phone")...), + psql.Arg(s.ReporterPhone), + }}) + } + + if s.Subscribe.IsValue() { + exprs = append(exprs, expr.Join{Sep: " = ", Exprs: []bob.Expression{ + psql.Quote(append(prefix, "subscribe")...), + psql.Arg(s.Subscribe), + }}) + } + + return exprs +} + +// FindPublicreportPool retrieves a single record by primary key +// If cols is empty Find will return all columns. +func FindPublicreportPool(ctx context.Context, exec bob.Executor, IDPK int32, cols ...string) (*PublicreportPool, error) { + if len(cols) == 0 { + return PublicreportPools.Query( + sm.Where(PublicreportPools.Columns.ID.EQ(psql.Arg(IDPK))), + ).One(ctx, exec) + } + + return PublicreportPools.Query( + sm.Where(PublicreportPools.Columns.ID.EQ(psql.Arg(IDPK))), + sm.Columns(PublicreportPools.Columns.Only(cols...)), + ).One(ctx, exec) +} + +// PublicreportPoolExists checks the presence of a single record by primary key +func PublicreportPoolExists(ctx context.Context, exec bob.Executor, IDPK int32) (bool, error) { + return PublicreportPools.Query( + sm.Where(PublicreportPools.Columns.ID.EQ(psql.Arg(IDPK))), + ).Exists(ctx, exec) +} + +// AfterQueryHook is called after PublicreportPool is retrieved from the database +func (o *PublicreportPool) AfterQueryHook(ctx context.Context, exec bob.Executor, queryType bob.QueryType) error { + var err error + + switch queryType { + case bob.QueryTypeSelect: + ctx, err = PublicreportPools.AfterSelectHooks.RunHooks(ctx, exec, PublicreportPoolSlice{o}) + case bob.QueryTypeInsert: + ctx, err = PublicreportPools.AfterInsertHooks.RunHooks(ctx, exec, PublicreportPoolSlice{o}) + case bob.QueryTypeUpdate: + ctx, err = PublicreportPools.AfterUpdateHooks.RunHooks(ctx, exec, PublicreportPoolSlice{o}) + case bob.QueryTypeDelete: + ctx, err = PublicreportPools.AfterDeleteHooks.RunHooks(ctx, exec, PublicreportPoolSlice{o}) + } + + return err +} + +// primaryKeyVals returns the primary key values of the PublicreportPool +func (o *PublicreportPool) primaryKeyVals() bob.Expression { + return psql.Arg(o.ID) +} + +func (o *PublicreportPool) pkEQ() dialect.Expression { + return psql.Quote("publicreport.pool", "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 PublicreportPool +func (o *PublicreportPool) Update(ctx context.Context, exec bob.Executor, s *PublicreportPoolSetter) error { + v, err := PublicreportPools.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 PublicreportPool record with an executor +func (o *PublicreportPool) Delete(ctx context.Context, exec bob.Executor) error { + _, err := PublicreportPools.Delete(dm.Where(o.pkEQ())).Exec(ctx, exec) + return err +} + +// Reload refreshes the PublicreportPool using the executor +func (o *PublicreportPool) Reload(ctx context.Context, exec bob.Executor) error { + o2, err := PublicreportPools.Query( + sm.Where(PublicreportPools.Columns.ID.EQ(psql.Arg(o.ID))), + ).One(ctx, exec) + if err != nil { + return err + } + o2.R = o.R + *o = *o2 + + return nil +} + +// AfterQueryHook is called after PublicreportPoolSlice is retrieved from the database +func (o PublicreportPoolSlice) AfterQueryHook(ctx context.Context, exec bob.Executor, queryType bob.QueryType) error { + var err error + + switch queryType { + case bob.QueryTypeSelect: + ctx, err = PublicreportPools.AfterSelectHooks.RunHooks(ctx, exec, o) + case bob.QueryTypeInsert: + ctx, err = PublicreportPools.AfterInsertHooks.RunHooks(ctx, exec, o) + case bob.QueryTypeUpdate: + ctx, err = PublicreportPools.AfterUpdateHooks.RunHooks(ctx, exec, o) + case bob.QueryTypeDelete: + ctx, err = PublicreportPools.AfterDeleteHooks.RunHooks(ctx, exec, o) + } + + return err +} + +func (o PublicreportPoolSlice) pkIN() dialect.Expression { + if len(o) == 0 { + return psql.Raw("NULL") + } + + return psql.Quote("publicreport.pool", "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 PublicreportPoolSlice) copyMatchingRows(from ...*PublicreportPool) { + for i, old := range o { + for _, new := range from { + if new.ID != old.ID { + continue + } + new.R = old.R + o[i] = new + break + } + } +} + +// UpdateMod modifies an update query with "WHERE primary_key IN (o...)" +func (o PublicreportPoolSlice) 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 PublicreportPools.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 *PublicreportPool: + o.copyMatchingRows(retrieved) + case []*PublicreportPool: + o.copyMatchingRows(retrieved...) + case PublicreportPoolSlice: + o.copyMatchingRows(retrieved...) + default: + // If the retrieved value is not a PublicreportPool or a slice of PublicreportPool + // then run the AfterUpdateHooks on the slice + _, err = PublicreportPools.AfterUpdateHooks.RunHooks(ctx, exec, o) + } + + return err + })) + + q.AppendWhere(o.pkIN()) + }) +} + +// DeleteMod modifies an delete query with "WHERE primary_key IN (o...)" +func (o PublicreportPoolSlice) 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 PublicreportPools.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 *PublicreportPool: + o.copyMatchingRows(retrieved) + case []*PublicreportPool: + o.copyMatchingRows(retrieved...) + case PublicreportPoolSlice: + o.copyMatchingRows(retrieved...) + default: + // If the retrieved value is not a PublicreportPool or a slice of PublicreportPool + // then run the AfterDeleteHooks on the slice + _, err = PublicreportPools.AfterDeleteHooks.RunHooks(ctx, exec, o) + } + + return err + })) + + q.AppendWhere(o.pkIN()) + }) +} + +func (o PublicreportPoolSlice) UpdateAll(ctx context.Context, exec bob.Executor, vals PublicreportPoolSetter) error { + if len(o) == 0 { + return nil + } + + _, err := PublicreportPools.Update(vals.UpdateMod(), o.UpdateMod()).All(ctx, exec) + return err +} + +func (o PublicreportPoolSlice) DeleteAll(ctx context.Context, exec bob.Executor) error { + if len(o) == 0 { + return nil + } + + _, err := PublicreportPools.Delete(o.DeleteMod()).Exec(ctx, exec) + return err +} + +func (o PublicreportPoolSlice) ReloadAll(ctx context.Context, exec bob.Executor) error { + if len(o) == 0 { + return nil + } + + o2, err := PublicreportPools.Query(sm.Where(o.pkIN())).All(ctx, exec) + if err != nil { + return err + } + + o.copyMatchingRows(o2...) + + return nil +} + +// PoolPhotos starts a query for related objects on publicreport.pool_photo +func (o *PublicreportPool) PoolPhotos(mods ...bob.Mod[*dialect.SelectQuery]) PublicreportPoolPhotosQuery { + return PublicreportPoolPhotos.Query(append(mods, + sm.Where(PublicreportPoolPhotos.Columns.PoolID.EQ(psql.Arg(o.ID))), + )...) +} + +func (os PublicreportPoolSlice) PoolPhotos(mods ...bob.Mod[*dialect.SelectQuery]) PublicreportPoolPhotosQuery { + 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 PublicreportPoolPhotos.Query(append(mods, + sm.Where(psql.Group(PublicreportPoolPhotos.Columns.PoolID).OP("IN", PKArgExpr)), + )...) +} + +func insertPublicreportPoolPoolPhotos0(ctx context.Context, exec bob.Executor, publicreportPoolPhotos1 []*PublicreportPoolPhotoSetter, publicreportPool0 *PublicreportPool) (PublicreportPoolPhotoSlice, error) { + for i := range publicreportPoolPhotos1 { + publicreportPoolPhotos1[i].PoolID = omit.From(publicreportPool0.ID) + } + + ret, err := PublicreportPoolPhotos.Insert(bob.ToMods(publicreportPoolPhotos1...)).All(ctx, exec) + if err != nil { + return ret, fmt.Errorf("insertPublicreportPoolPoolPhotos0: %w", err) + } + + return ret, nil +} + +func attachPublicreportPoolPoolPhotos0(ctx context.Context, exec bob.Executor, count int, publicreportPoolPhotos1 PublicreportPoolPhotoSlice, publicreportPool0 *PublicreportPool) (PublicreportPoolPhotoSlice, error) { + setter := &PublicreportPoolPhotoSetter{ + PoolID: omit.From(publicreportPool0.ID), + } + + err := publicreportPoolPhotos1.UpdateAll(ctx, exec, *setter) + if err != nil { + return nil, fmt.Errorf("attachPublicreportPoolPoolPhotos0: %w", err) + } + + return publicreportPoolPhotos1, nil +} + +func (publicreportPool0 *PublicreportPool) InsertPoolPhotos(ctx context.Context, exec bob.Executor, related ...*PublicreportPoolPhotoSetter) error { + if len(related) == 0 { + return nil + } + + var err error + + publicreportPoolPhotos1, err := insertPublicreportPoolPoolPhotos0(ctx, exec, related, publicreportPool0) + if err != nil { + return err + } + + publicreportPool0.R.PoolPhotos = append(publicreportPool0.R.PoolPhotos, publicreportPoolPhotos1...) + + for _, rel := range publicreportPoolPhotos1 { + rel.R.Pool = publicreportPool0 + } + return nil +} + +func (publicreportPool0 *PublicreportPool) AttachPoolPhotos(ctx context.Context, exec bob.Executor, related ...*PublicreportPoolPhoto) error { + if len(related) == 0 { + return nil + } + + var err error + publicreportPoolPhotos1 := PublicreportPoolPhotoSlice(related) + + _, err = attachPublicreportPoolPoolPhotos0(ctx, exec, len(related), publicreportPoolPhotos1, publicreportPool0) + if err != nil { + return err + } + + publicreportPool0.R.PoolPhotos = append(publicreportPool0.R.PoolPhotos, publicreportPoolPhotos1...) + + for _, rel := range related { + rel.R.Pool = publicreportPool0 + } + + return nil +} + +type publicreportPoolWhere[Q psql.Filterable] struct { + ID psql.WhereMod[Q, int32] + AccessComments psql.WhereMod[Q, string] + AccessGate psql.WhereMod[Q, bool] + AccessFence psql.WhereMod[Q, bool] + AccessLocked psql.WhereMod[Q, bool] + AccessDog psql.WhereMod[Q, bool] + AccessOther psql.WhereMod[Q, bool] + Address psql.WhereMod[Q, string] + AddressCountry psql.WhereMod[Q, string] + AddressPostCode psql.WhereMod[Q, string] + AddressPlace psql.WhereMod[Q, string] + AddressStreet psql.WhereMod[Q, string] + AddressRegion psql.WhereMod[Q, string] + Comments psql.WhereMod[Q, string] + Created psql.WhereMod[Q, time.Time] + H3cell psql.WhereNullMod[Q, string] + HasAdult psql.WhereMod[Q, bool] + HasLarvae psql.WhereMod[Q, bool] + HasPupae psql.WhereMod[Q, bool] + Location psql.WhereNullMod[Q, string] + MapZoom psql.WhereMod[Q, float64] + OwnerEmail psql.WhereMod[Q, string] + OwnerName psql.WhereMod[Q, string] + OwnerPhone psql.WhereMod[Q, string] + PublicID psql.WhereMod[Q, string] + ReporterEmail psql.WhereMod[Q, string] + ReporterName psql.WhereMod[Q, string] + ReporterPhone psql.WhereMod[Q, string] + Subscribe psql.WhereMod[Q, bool] +} + +func (publicreportPoolWhere[Q]) AliasedAs(alias string) publicreportPoolWhere[Q] { + return buildPublicreportPoolWhere[Q](buildPublicreportPoolColumns(alias)) +} + +func buildPublicreportPoolWhere[Q psql.Filterable](cols publicreportPoolColumns) publicreportPoolWhere[Q] { + return publicreportPoolWhere[Q]{ + ID: psql.Where[Q, int32](cols.ID), + AccessComments: psql.Where[Q, string](cols.AccessComments), + AccessGate: psql.Where[Q, bool](cols.AccessGate), + AccessFence: psql.Where[Q, bool](cols.AccessFence), + AccessLocked: psql.Where[Q, bool](cols.AccessLocked), + AccessDog: psql.Where[Q, bool](cols.AccessDog), + AccessOther: psql.Where[Q, bool](cols.AccessOther), + Address: psql.Where[Q, string](cols.Address), + AddressCountry: psql.Where[Q, string](cols.AddressCountry), + AddressPostCode: psql.Where[Q, string](cols.AddressPostCode), + AddressPlace: psql.Where[Q, string](cols.AddressPlace), + AddressStreet: psql.Where[Q, string](cols.AddressStreet), + AddressRegion: psql.Where[Q, string](cols.AddressRegion), + Comments: psql.Where[Q, string](cols.Comments), + Created: psql.Where[Q, time.Time](cols.Created), + H3cell: psql.WhereNull[Q, string](cols.H3cell), + HasAdult: psql.Where[Q, bool](cols.HasAdult), + HasLarvae: psql.Where[Q, bool](cols.HasLarvae), + HasPupae: psql.Where[Q, bool](cols.HasPupae), + Location: psql.WhereNull[Q, string](cols.Location), + MapZoom: psql.Where[Q, float64](cols.MapZoom), + OwnerEmail: psql.Where[Q, string](cols.OwnerEmail), + OwnerName: psql.Where[Q, string](cols.OwnerName), + OwnerPhone: psql.Where[Q, string](cols.OwnerPhone), + PublicID: psql.Where[Q, string](cols.PublicID), + ReporterEmail: psql.Where[Q, string](cols.ReporterEmail), + ReporterName: psql.Where[Q, string](cols.ReporterName), + ReporterPhone: psql.Where[Q, string](cols.ReporterPhone), + Subscribe: psql.Where[Q, bool](cols.Subscribe), + } +} + +func (o *PublicreportPool) Preload(name string, retrieved any) error { + if o == nil { + return nil + } + + switch name { + case "PoolPhotos": + rels, ok := retrieved.(PublicreportPoolPhotoSlice) + if !ok { + return fmt.Errorf("publicreportPool cannot load %T as %q", retrieved, name) + } + + o.R.PoolPhotos = rels + + for _, rel := range rels { + if rel != nil { + rel.R.Pool = o + } + } + return nil + default: + return fmt.Errorf("publicreportPool has no relationship %q", name) + } +} + +type publicreportPoolPreloader struct{} + +func buildPublicreportPoolPreloader() publicreportPoolPreloader { + return publicreportPoolPreloader{} +} + +type publicreportPoolThenLoader[Q orm.Loadable] struct { + PoolPhotos func(...bob.Mod[*dialect.SelectQuery]) orm.Loader[Q] +} + +func buildPublicreportPoolThenLoader[Q orm.Loadable]() publicreportPoolThenLoader[Q] { + type PoolPhotosLoadInterface interface { + LoadPoolPhotos(context.Context, bob.Executor, ...bob.Mod[*dialect.SelectQuery]) error + } + + return publicreportPoolThenLoader[Q]{ + PoolPhotos: thenLoadBuilder[Q]( + "PoolPhotos", + func(ctx context.Context, exec bob.Executor, retrieved PoolPhotosLoadInterface, mods ...bob.Mod[*dialect.SelectQuery]) error { + return retrieved.LoadPoolPhotos(ctx, exec, mods...) + }, + ), + } +} + +// LoadPoolPhotos loads the publicreportPool's PoolPhotos into the .R struct +func (o *PublicreportPool) LoadPoolPhotos(ctx context.Context, exec bob.Executor, mods ...bob.Mod[*dialect.SelectQuery]) error { + if o == nil { + return nil + } + + // Reset the relationship + o.R.PoolPhotos = nil + + related, err := o.PoolPhotos(mods...).All(ctx, exec) + if err != nil { + return err + } + + for _, rel := range related { + rel.R.Pool = o + } + + o.R.PoolPhotos = related + return nil +} + +// LoadPoolPhotos loads the publicreportPool's PoolPhotos into the .R struct +func (os PublicreportPoolSlice) LoadPoolPhotos(ctx context.Context, exec bob.Executor, mods ...bob.Mod[*dialect.SelectQuery]) error { + if len(os) == 0 { + return nil + } + + publicreportPoolPhotos, err := os.PoolPhotos(mods...).All(ctx, exec) + if err != nil { + return err + } + + for _, o := range os { + if o == nil { + continue + } + + o.R.PoolPhotos = nil + } + + for _, o := range os { + if o == nil { + continue + } + + for _, rel := range publicreportPoolPhotos { + + if !(o.ID == rel.PoolID) { + continue + } + + rel.R.Pool = o + + o.R.PoolPhotos = append(o.R.PoolPhotos, rel) + } + } + + return nil +} + +type publicreportPoolJoins[Q dialect.Joinable] struct { + typ string + PoolPhotos modAs[Q, publicreportPoolPhotoColumns] +} + +func (j publicreportPoolJoins[Q]) aliasedAs(alias string) publicreportPoolJoins[Q] { + return buildPublicreportPoolJoins[Q](buildPublicreportPoolColumns(alias), j.typ) +} + +func buildPublicreportPoolJoins[Q dialect.Joinable](cols publicreportPoolColumns, typ string) publicreportPoolJoins[Q] { + return publicreportPoolJoins[Q]{ + typ: typ, + PoolPhotos: modAs[Q, publicreportPoolPhotoColumns]{ + c: PublicreportPoolPhotos.Columns, + f: func(to publicreportPoolPhotoColumns) bob.Mod[Q] { + mods := make(mods.QueryMods[Q], 0, 1) + + { + mods = append(mods, dialect.Join[Q](typ, PublicreportPoolPhotos.Name().As(to.Alias())).On( + to.PoolID.EQ(cols.ID), + )) + } + + return mods + }, + }, + } +} diff --git a/db/models/publicreport.pool_photo.bob.go b/db/models/publicreport.pool_photo.bob.go new file mode 100644 index 00000000..11a67efb --- /dev/null +++ b/db/models/publicreport.pool_photo.bob.go @@ -0,0 +1,678 @@ +// Code generated by BobGen psql v0.0.4-0.20260105020634-53e08d840e47+dirty. 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/aarondl/opt/omit" + "github.com/google/uuid" + "github.com/stephenafamo/bob" + "github.com/stephenafamo/bob/dialect/psql" + "github.com/stephenafamo/bob/dialect/psql/dialect" + "github.com/stephenafamo/bob/dialect/psql/dm" + "github.com/stephenafamo/bob/dialect/psql/sm" + "github.com/stephenafamo/bob/dialect/psql/um" + "github.com/stephenafamo/bob/expr" + "github.com/stephenafamo/bob/mods" + "github.com/stephenafamo/bob/orm" + "github.com/stephenafamo/bob/types/pgtypes" +) + +// PublicreportPoolPhoto is an object representing the database table. +type PublicreportPoolPhoto struct { + ID int32 `db:"id,pk" ` + Size int64 `db:"size" ` + Filename string `db:"filename" ` + PoolID int32 `db:"pool_id" ` + UUID uuid.UUID `db:"uuid" ` + + R publicreportPoolPhotoR `db:"-" ` +} + +// PublicreportPoolPhotoSlice is an alias for a slice of pointers to PublicreportPoolPhoto. +// This should almost always be used instead of []*PublicreportPoolPhoto. +type PublicreportPoolPhotoSlice []*PublicreportPoolPhoto + +// PublicreportPoolPhotos contains methods to work with the pool_photo table +var PublicreportPoolPhotos = psql.NewTablex[*PublicreportPoolPhoto, PublicreportPoolPhotoSlice, *PublicreportPoolPhotoSetter]("publicreport", "pool_photo", buildPublicreportPoolPhotoColumns("publicreport.pool_photo")) + +// PublicreportPoolPhotosQuery is a query on the pool_photo table +type PublicreportPoolPhotosQuery = *psql.ViewQuery[*PublicreportPoolPhoto, PublicreportPoolPhotoSlice] + +// publicreportPoolPhotoR is where relationships are stored. +type publicreportPoolPhotoR struct { + Pool *PublicreportPool // publicreport.pool_photo.pool_photo_pool_id_fkey +} + +func buildPublicreportPoolPhotoColumns(alias string) publicreportPoolPhotoColumns { + return publicreportPoolPhotoColumns{ + ColumnsExpr: expr.NewColumnsExpr( + "id", "size", "filename", "pool_id", "uuid", + ).WithParent("publicreport.pool_photo"), + tableAlias: alias, + ID: psql.Quote(alias, "id"), + Size: psql.Quote(alias, "size"), + Filename: psql.Quote(alias, "filename"), + PoolID: psql.Quote(alias, "pool_id"), + UUID: psql.Quote(alias, "uuid"), + } +} + +type publicreportPoolPhotoColumns struct { + expr.ColumnsExpr + tableAlias string + ID psql.Expression + Size psql.Expression + Filename psql.Expression + PoolID psql.Expression + UUID psql.Expression +} + +func (c publicreportPoolPhotoColumns) Alias() string { + return c.tableAlias +} + +func (publicreportPoolPhotoColumns) AliasedAs(alias string) publicreportPoolPhotoColumns { + return buildPublicreportPoolPhotoColumns(alias) +} + +// PublicreportPoolPhotoSetter is used for insert/upsert/update operations +// All values are optional, and do not have to be set +// Generated columns are not included +type PublicreportPoolPhotoSetter struct { + ID omit.Val[int32] `db:"id,pk" ` + Size omit.Val[int64] `db:"size" ` + Filename omit.Val[string] `db:"filename" ` + PoolID omit.Val[int32] `db:"pool_id" ` + UUID omit.Val[uuid.UUID] `db:"uuid" ` +} + +func (s PublicreportPoolPhotoSetter) SetColumns() []string { + vals := make([]string, 0, 5) + if s.ID.IsValue() { + vals = append(vals, "id") + } + if s.Size.IsValue() { + vals = append(vals, "size") + } + if s.Filename.IsValue() { + vals = append(vals, "filename") + } + if s.PoolID.IsValue() { + vals = append(vals, "pool_id") + } + if s.UUID.IsValue() { + vals = append(vals, "uuid") + } + return vals +} + +func (s PublicreportPoolPhotoSetter) Overwrite(t *PublicreportPoolPhoto) { + if s.ID.IsValue() { + t.ID = s.ID.MustGet() + } + if s.Size.IsValue() { + t.Size = s.Size.MustGet() + } + if s.Filename.IsValue() { + t.Filename = s.Filename.MustGet() + } + if s.PoolID.IsValue() { + t.PoolID = s.PoolID.MustGet() + } + if s.UUID.IsValue() { + t.UUID = s.UUID.MustGet() + } +} + +func (s *PublicreportPoolPhotoSetter) Apply(q *dialect.InsertQuery) { + q.AppendHooks(func(ctx context.Context, exec bob.Executor) (context.Context, error) { + return PublicreportPoolPhotos.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, 5) + if s.ID.IsValue() { + vals[0] = psql.Arg(s.ID.MustGet()) + } else { + vals[0] = psql.Raw("DEFAULT") + } + + if s.Size.IsValue() { + vals[1] = psql.Arg(s.Size.MustGet()) + } else { + vals[1] = psql.Raw("DEFAULT") + } + + if s.Filename.IsValue() { + vals[2] = psql.Arg(s.Filename.MustGet()) + } else { + vals[2] = psql.Raw("DEFAULT") + } + + if s.PoolID.IsValue() { + vals[3] = psql.Arg(s.PoolID.MustGet()) + } else { + vals[3] = psql.Raw("DEFAULT") + } + + if s.UUID.IsValue() { + vals[4] = psql.Arg(s.UUID.MustGet()) + } else { + vals[4] = psql.Raw("DEFAULT") + } + + return bob.ExpressSlice(ctx, w, d, start, vals, "", ", ", "") + })) +} + +func (s PublicreportPoolPhotoSetter) UpdateMod() bob.Mod[*dialect.UpdateQuery] { + return um.Set(s.Expressions()...) +} + +func (s PublicreportPoolPhotoSetter) Expressions(prefix ...string) []bob.Expression { + exprs := make([]bob.Expression, 0, 5) + + if s.ID.IsValue() { + exprs = append(exprs, expr.Join{Sep: " = ", Exprs: []bob.Expression{ + psql.Quote(append(prefix, "id")...), + psql.Arg(s.ID), + }}) + } + + if s.Size.IsValue() { + exprs = append(exprs, expr.Join{Sep: " = ", Exprs: []bob.Expression{ + psql.Quote(append(prefix, "size")...), + psql.Arg(s.Size), + }}) + } + + if s.Filename.IsValue() { + exprs = append(exprs, expr.Join{Sep: " = ", Exprs: []bob.Expression{ + psql.Quote(append(prefix, "filename")...), + psql.Arg(s.Filename), + }}) + } + + if s.PoolID.IsValue() { + exprs = append(exprs, expr.Join{Sep: " = ", Exprs: []bob.Expression{ + psql.Quote(append(prefix, "pool_id")...), + psql.Arg(s.PoolID), + }}) + } + + if s.UUID.IsValue() { + exprs = append(exprs, expr.Join{Sep: " = ", Exprs: []bob.Expression{ + psql.Quote(append(prefix, "uuid")...), + psql.Arg(s.UUID), + }}) + } + + return exprs +} + +// FindPublicreportPoolPhoto retrieves a single record by primary key +// If cols is empty Find will return all columns. +func FindPublicreportPoolPhoto(ctx context.Context, exec bob.Executor, IDPK int32, cols ...string) (*PublicreportPoolPhoto, error) { + if len(cols) == 0 { + return PublicreportPoolPhotos.Query( + sm.Where(PublicreportPoolPhotos.Columns.ID.EQ(psql.Arg(IDPK))), + ).One(ctx, exec) + } + + return PublicreportPoolPhotos.Query( + sm.Where(PublicreportPoolPhotos.Columns.ID.EQ(psql.Arg(IDPK))), + sm.Columns(PublicreportPoolPhotos.Columns.Only(cols...)), + ).One(ctx, exec) +} + +// PublicreportPoolPhotoExists checks the presence of a single record by primary key +func PublicreportPoolPhotoExists(ctx context.Context, exec bob.Executor, IDPK int32) (bool, error) { + return PublicreportPoolPhotos.Query( + sm.Where(PublicreportPoolPhotos.Columns.ID.EQ(psql.Arg(IDPK))), + ).Exists(ctx, exec) +} + +// AfterQueryHook is called after PublicreportPoolPhoto is retrieved from the database +func (o *PublicreportPoolPhoto) AfterQueryHook(ctx context.Context, exec bob.Executor, queryType bob.QueryType) error { + var err error + + switch queryType { + case bob.QueryTypeSelect: + ctx, err = PublicreportPoolPhotos.AfterSelectHooks.RunHooks(ctx, exec, PublicreportPoolPhotoSlice{o}) + case bob.QueryTypeInsert: + ctx, err = PublicreportPoolPhotos.AfterInsertHooks.RunHooks(ctx, exec, PublicreportPoolPhotoSlice{o}) + case bob.QueryTypeUpdate: + ctx, err = PublicreportPoolPhotos.AfterUpdateHooks.RunHooks(ctx, exec, PublicreportPoolPhotoSlice{o}) + case bob.QueryTypeDelete: + ctx, err = PublicreportPoolPhotos.AfterDeleteHooks.RunHooks(ctx, exec, PublicreportPoolPhotoSlice{o}) + } + + return err +} + +// primaryKeyVals returns the primary key values of the PublicreportPoolPhoto +func (o *PublicreportPoolPhoto) primaryKeyVals() bob.Expression { + return psql.Arg(o.ID) +} + +func (o *PublicreportPoolPhoto) pkEQ() dialect.Expression { + return psql.Quote("publicreport.pool_photo", "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 PublicreportPoolPhoto +func (o *PublicreportPoolPhoto) Update(ctx context.Context, exec bob.Executor, s *PublicreportPoolPhotoSetter) error { + v, err := PublicreportPoolPhotos.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 PublicreportPoolPhoto record with an executor +func (o *PublicreportPoolPhoto) Delete(ctx context.Context, exec bob.Executor) error { + _, err := PublicreportPoolPhotos.Delete(dm.Where(o.pkEQ())).Exec(ctx, exec) + return err +} + +// Reload refreshes the PublicreportPoolPhoto using the executor +func (o *PublicreportPoolPhoto) Reload(ctx context.Context, exec bob.Executor) error { + o2, err := PublicreportPoolPhotos.Query( + sm.Where(PublicreportPoolPhotos.Columns.ID.EQ(psql.Arg(o.ID))), + ).One(ctx, exec) + if err != nil { + return err + } + o2.R = o.R + *o = *o2 + + return nil +} + +// AfterQueryHook is called after PublicreportPoolPhotoSlice is retrieved from the database +func (o PublicreportPoolPhotoSlice) AfterQueryHook(ctx context.Context, exec bob.Executor, queryType bob.QueryType) error { + var err error + + switch queryType { + case bob.QueryTypeSelect: + ctx, err = PublicreportPoolPhotos.AfterSelectHooks.RunHooks(ctx, exec, o) + case bob.QueryTypeInsert: + ctx, err = PublicreportPoolPhotos.AfterInsertHooks.RunHooks(ctx, exec, o) + case bob.QueryTypeUpdate: + ctx, err = PublicreportPoolPhotos.AfterUpdateHooks.RunHooks(ctx, exec, o) + case bob.QueryTypeDelete: + ctx, err = PublicreportPoolPhotos.AfterDeleteHooks.RunHooks(ctx, exec, o) + } + + return err +} + +func (o PublicreportPoolPhotoSlice) pkIN() dialect.Expression { + if len(o) == 0 { + return psql.Raw("NULL") + } + + return psql.Quote("publicreport.pool_photo", "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 PublicreportPoolPhotoSlice) copyMatchingRows(from ...*PublicreportPoolPhoto) { + for i, old := range o { + for _, new := range from { + if new.ID != old.ID { + continue + } + new.R = old.R + o[i] = new + break + } + } +} + +// UpdateMod modifies an update query with "WHERE primary_key IN (o...)" +func (o PublicreportPoolPhotoSlice) 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 PublicreportPoolPhotos.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 *PublicreportPoolPhoto: + o.copyMatchingRows(retrieved) + case []*PublicreportPoolPhoto: + o.copyMatchingRows(retrieved...) + case PublicreportPoolPhotoSlice: + o.copyMatchingRows(retrieved...) + default: + // If the retrieved value is not a PublicreportPoolPhoto or a slice of PublicreportPoolPhoto + // then run the AfterUpdateHooks on the slice + _, err = PublicreportPoolPhotos.AfterUpdateHooks.RunHooks(ctx, exec, o) + } + + return err + })) + + q.AppendWhere(o.pkIN()) + }) +} + +// DeleteMod modifies an delete query with "WHERE primary_key IN (o...)" +func (o PublicreportPoolPhotoSlice) 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 PublicreportPoolPhotos.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 *PublicreportPoolPhoto: + o.copyMatchingRows(retrieved) + case []*PublicreportPoolPhoto: + o.copyMatchingRows(retrieved...) + case PublicreportPoolPhotoSlice: + o.copyMatchingRows(retrieved...) + default: + // If the retrieved value is not a PublicreportPoolPhoto or a slice of PublicreportPoolPhoto + // then run the AfterDeleteHooks on the slice + _, err = PublicreportPoolPhotos.AfterDeleteHooks.RunHooks(ctx, exec, o) + } + + return err + })) + + q.AppendWhere(o.pkIN()) + }) +} + +func (o PublicreportPoolPhotoSlice) UpdateAll(ctx context.Context, exec bob.Executor, vals PublicreportPoolPhotoSetter) error { + if len(o) == 0 { + return nil + } + + _, err := PublicreportPoolPhotos.Update(vals.UpdateMod(), o.UpdateMod()).All(ctx, exec) + return err +} + +func (o PublicreportPoolPhotoSlice) DeleteAll(ctx context.Context, exec bob.Executor) error { + if len(o) == 0 { + return nil + } + + _, err := PublicreportPoolPhotos.Delete(o.DeleteMod()).Exec(ctx, exec) + return err +} + +func (o PublicreportPoolPhotoSlice) ReloadAll(ctx context.Context, exec bob.Executor) error { + if len(o) == 0 { + return nil + } + + o2, err := PublicreportPoolPhotos.Query(sm.Where(o.pkIN())).All(ctx, exec) + if err != nil { + return err + } + + o.copyMatchingRows(o2...) + + return nil +} + +// Pool starts a query for related objects on publicreport.pool +func (o *PublicreportPoolPhoto) Pool(mods ...bob.Mod[*dialect.SelectQuery]) PublicreportPoolsQuery { + return PublicreportPools.Query(append(mods, + sm.Where(PublicreportPools.Columns.ID.EQ(psql.Arg(o.PoolID))), + )...) +} + +func (os PublicreportPoolPhotoSlice) Pool(mods ...bob.Mod[*dialect.SelectQuery]) PublicreportPoolsQuery { + pkPoolID := make(pgtypes.Array[int32], 0, len(os)) + for _, o := range os { + if o == nil { + continue + } + pkPoolID = append(pkPoolID, o.PoolID) + } + PKArgExpr := psql.Select(sm.Columns( + psql.F("unnest", psql.Cast(psql.Arg(pkPoolID), "integer[]")), + )) + + return PublicreportPools.Query(append(mods, + sm.Where(psql.Group(PublicreportPools.Columns.ID).OP("IN", PKArgExpr)), + )...) +} + +func attachPublicreportPoolPhotoPool0(ctx context.Context, exec bob.Executor, count int, publicreportPoolPhoto0 *PublicreportPoolPhoto, publicreportPool1 *PublicreportPool) (*PublicreportPoolPhoto, error) { + setter := &PublicreportPoolPhotoSetter{ + PoolID: omit.From(publicreportPool1.ID), + } + + err := publicreportPoolPhoto0.Update(ctx, exec, setter) + if err != nil { + return nil, fmt.Errorf("attachPublicreportPoolPhotoPool0: %w", err) + } + + return publicreportPoolPhoto0, nil +} + +func (publicreportPoolPhoto0 *PublicreportPoolPhoto) InsertPool(ctx context.Context, exec bob.Executor, related *PublicreportPoolSetter) error { + var err error + + publicreportPool1, err := PublicreportPools.Insert(related).One(ctx, exec) + if err != nil { + return fmt.Errorf("inserting related objects: %w", err) + } + + _, err = attachPublicreportPoolPhotoPool0(ctx, exec, 1, publicreportPoolPhoto0, publicreportPool1) + if err != nil { + return err + } + + publicreportPoolPhoto0.R.Pool = publicreportPool1 + + publicreportPool1.R.PoolPhotos = append(publicreportPool1.R.PoolPhotos, publicreportPoolPhoto0) + + return nil +} + +func (publicreportPoolPhoto0 *PublicreportPoolPhoto) AttachPool(ctx context.Context, exec bob.Executor, publicreportPool1 *PublicreportPool) error { + var err error + + _, err = attachPublicreportPoolPhotoPool0(ctx, exec, 1, publicreportPoolPhoto0, publicreportPool1) + if err != nil { + return err + } + + publicreportPoolPhoto0.R.Pool = publicreportPool1 + + publicreportPool1.R.PoolPhotos = append(publicreportPool1.R.PoolPhotos, publicreportPoolPhoto0) + + return nil +} + +type publicreportPoolPhotoWhere[Q psql.Filterable] struct { + ID psql.WhereMod[Q, int32] + Size psql.WhereMod[Q, int64] + Filename psql.WhereMod[Q, string] + PoolID psql.WhereMod[Q, int32] + UUID psql.WhereMod[Q, uuid.UUID] +} + +func (publicreportPoolPhotoWhere[Q]) AliasedAs(alias string) publicreportPoolPhotoWhere[Q] { + return buildPublicreportPoolPhotoWhere[Q](buildPublicreportPoolPhotoColumns(alias)) +} + +func buildPublicreportPoolPhotoWhere[Q psql.Filterable](cols publicreportPoolPhotoColumns) publicreportPoolPhotoWhere[Q] { + return publicreportPoolPhotoWhere[Q]{ + ID: psql.Where[Q, int32](cols.ID), + Size: psql.Where[Q, int64](cols.Size), + Filename: psql.Where[Q, string](cols.Filename), + PoolID: psql.Where[Q, int32](cols.PoolID), + UUID: psql.Where[Q, uuid.UUID](cols.UUID), + } +} + +func (o *PublicreportPoolPhoto) Preload(name string, retrieved any) error { + if o == nil { + return nil + } + + switch name { + case "Pool": + rel, ok := retrieved.(*PublicreportPool) + if !ok { + return fmt.Errorf("publicreportPoolPhoto cannot load %T as %q", retrieved, name) + } + + o.R.Pool = rel + + if rel != nil { + rel.R.PoolPhotos = PublicreportPoolPhotoSlice{o} + } + return nil + default: + return fmt.Errorf("publicreportPoolPhoto has no relationship %q", name) + } +} + +type publicreportPoolPhotoPreloader struct { + Pool func(...psql.PreloadOption) psql.Preloader +} + +func buildPublicreportPoolPhotoPreloader() publicreportPoolPhotoPreloader { + return publicreportPoolPhotoPreloader{ + Pool: func(opts ...psql.PreloadOption) psql.Preloader { + return psql.Preload[*PublicreportPool, PublicreportPoolSlice](psql.PreloadRel{ + Name: "Pool", + Sides: []psql.PreloadSide{ + { + From: PublicreportPoolPhotos, + To: PublicreportPools, + FromColumns: []string{"pool_id"}, + ToColumns: []string{"id"}, + }, + }, + }, PublicreportPools.Columns.Names(), opts...) + }, + } +} + +type publicreportPoolPhotoThenLoader[Q orm.Loadable] struct { + Pool func(...bob.Mod[*dialect.SelectQuery]) orm.Loader[Q] +} + +func buildPublicreportPoolPhotoThenLoader[Q orm.Loadable]() publicreportPoolPhotoThenLoader[Q] { + type PoolLoadInterface interface { + LoadPool(context.Context, bob.Executor, ...bob.Mod[*dialect.SelectQuery]) error + } + + return publicreportPoolPhotoThenLoader[Q]{ + Pool: thenLoadBuilder[Q]( + "Pool", + func(ctx context.Context, exec bob.Executor, retrieved PoolLoadInterface, mods ...bob.Mod[*dialect.SelectQuery]) error { + return retrieved.LoadPool(ctx, exec, mods...) + }, + ), + } +} + +// LoadPool loads the publicreportPoolPhoto's Pool into the .R struct +func (o *PublicreportPoolPhoto) LoadPool(ctx context.Context, exec bob.Executor, mods ...bob.Mod[*dialect.SelectQuery]) error { + if o == nil { + return nil + } + + // Reset the relationship + o.R.Pool = nil + + related, err := o.Pool(mods...).One(ctx, exec) + if err != nil { + return err + } + + related.R.PoolPhotos = PublicreportPoolPhotoSlice{o} + + o.R.Pool = related + return nil +} + +// LoadPool loads the publicreportPoolPhoto's Pool into the .R struct +func (os PublicreportPoolPhotoSlice) LoadPool(ctx context.Context, exec bob.Executor, mods ...bob.Mod[*dialect.SelectQuery]) error { + if len(os) == 0 { + return nil + } + + publicreportPools, err := os.Pool(mods...).All(ctx, exec) + if err != nil { + return err + } + + for _, o := range os { + if o == nil { + continue + } + + for _, rel := range publicreportPools { + + if !(o.PoolID == rel.ID) { + continue + } + + rel.R.PoolPhotos = append(rel.R.PoolPhotos, o) + + o.R.Pool = rel + break + } + } + + return nil +} + +type publicreportPoolPhotoJoins[Q dialect.Joinable] struct { + typ string + Pool modAs[Q, publicreportPoolColumns] +} + +func (j publicreportPoolPhotoJoins[Q]) aliasedAs(alias string) publicreportPoolPhotoJoins[Q] { + return buildPublicreportPoolPhotoJoins[Q](buildPublicreportPoolPhotoColumns(alias), j.typ) +} + +func buildPublicreportPoolPhotoJoins[Q dialect.Joinable](cols publicreportPoolPhotoColumns, typ string) publicreportPoolPhotoJoins[Q] { + return publicreportPoolPhotoJoins[Q]{ + typ: typ, + Pool: modAs[Q, publicreportPoolColumns]{ + c: PublicreportPools.Columns, + f: func(to publicreportPoolColumns) bob.Mod[Q] { + mods := make(mods.QueryMods[Q], 0, 1) + + { + mods = append(mods, dialect.Join[Q](typ, PublicreportPools.Name().As(to.Alias())).On( + to.ID.EQ(cols.PoolID), + )) + } + + return mods + }, + }, + } +} diff --git a/h3utils/h3.go b/h3utils/h3.go index c178de09..c5c6082d 100644 --- a/h3utils/h3.go +++ b/h3utils/h3.go @@ -101,3 +101,44 @@ func CellToPostgisGeometry(c h3.Cell) (string, error) { return fmt.Sprintf("POLYGON((%s))", sb.String()), nil } + +// Convert from an accuracy in meters of GPS coordinates to the H3 Resolution that has at least +// the same area. In other words, for a GPS coordinate accuracy of 2m you have pi*(2m)^2 or ~12.5m^2 +// of area which corresponds to resolution 13 (average area of 43.87^2) vs resolution 14 (average area 6.26m^2) +// See https://h3geo.org/docs/core-library/restable +func MeterAccuracyToH3Resolution(accuracy_in_meters float64) int { + area := accuracy_in_meters * accuracy_in_meters * 3.1415 + if area < 0.895 { + return 15 + } else if area < 6.267 { + return 14 + } else if area < 43.87 { + return 13 + } else if area < 307.092 { + return 12 + } else if area < 2149.643 { + return 11 + } else if area < 15_047.502 { + return 10 + } else if area < 105_332.513 { + return 9 + } else if area < 737_327.598 { + return 8 + } else if area < 5_161_293.360 { + return 7 + } else if area < 36_129_062.164 { + return 6 + } else if area < 252_903_858.182 { + return 5 + } else if area < 1_770_347_654.491 { + return 4 + } else if area < 12_393_434_655.088 { + return 3 + } else if area < 86_801_780_398.997 { + return 2 + } else if area < 609_788_441_794.134 { + return 1 + } else { + return 0 + } +} diff --git a/public-report/endpoint.go b/public-report/endpoint.go index d8cb8041..9b871eb1 100644 --- a/public-report/endpoint.go +++ b/public-report/endpoint.go @@ -1,47 +1,21 @@ package publicreport import ( - "bytes" "fmt" - "io" "net/http" "strconv" "time" - "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/htmlpage" - "github.com/Gleipnir-Technology/nidus-sync/userfile" "github.com/aarondl/opt/omit" - "github.com/aarondl/opt/omitnull" - "github.com/go-chi/chi/v5" - "github.com/google/uuid" "github.com/rs/zerolog/log" "github.com/stephenafamo/bob/dialect/psql" "github.com/stephenafamo/bob/dialect/psql/um" ) -func Router() chi.Router { - r := chi.NewRouter() - r.Get("/", getRoot) - r.Get("/nuisance", getNuisance) - r.Post("/nuisance-submit", postNuisance) - r.Get("/nuisance-submit-complete", getNuisanceSubmitComplete) - r.Get("/pool", getPool) - r.Get("/quick", getQuick) - r.Post("/quick-submit", postQuick) - r.Get("/quick-submit-complete", getQuickSubmitComplete) - r.Post("/register-notifications", postRegisterNotifications) - r.Get("/register-notifications-complete", getRegisterNotificationsComplete) - r.Get("/status", getStatus) - localFS := http.Dir("./static") - htmlpage.FileServer(r, "/static", localFS, EmbeddedStaticFS, "static") - return r -} - func getRoot(w http.ResponseWriter, r *http.Request) { htmlpage.RenderOrError( w, @@ -67,32 +41,6 @@ func getNuisanceSubmitComplete(w http.ResponseWriter, r *http.Request) { }, ) } -func getPool(w http.ResponseWriter, r *http.Request) { - htmlpage.RenderOrError( - w, - Pool, - ContextPool{ - MapboxToken: config.MapboxToken, - }, - ) -} -func getQuick(w http.ResponseWriter, r *http.Request) { - htmlpage.RenderOrError( - w, - Quick, - ContextQuick{}, - ) -} -func getQuickSubmitComplete(w http.ResponseWriter, r *http.Request) { - report := r.URL.Query().Get("report") - htmlpage.RenderOrError( - w, - QuickSubmitComplete, - ContextQuickSubmitComplete{ - ReportID: report, - }, - ) -} func getRegisterNotificationsComplete(w http.ResponseWriter, r *http.Request) { report := r.URL.Query().Get("report") htmlpage.RenderOrError( @@ -135,7 +83,6 @@ func postNuisance(w http.ResponseWriter, r *http.Request) { return } - inspection_type_str := postFormValueOrNone(r, "inspection-type") var inspection_type enums.PublicreportNuisanceinspectiontype err = inspection_type.Scan(inspection_type_str) @@ -188,29 +135,29 @@ func postNuisance(w http.ResponseWriter, r *http.Request) { log.Info().Str("address", address).Str("name", name).Msg("Got report") setter := models.PublicreportNuisanceSetter{ - AdditionalInfo: omit.From(additional_info), - Created: omit.From(time.Now()), - Duration: omit.From(duration), - Email: omit.From(email), - InspectionType: omit.From(inspection_type), - Location: omit.From(location), + AdditionalInfo: omit.From(additional_info), + Created: omit.From(time.Now()), + Duration: omit.From(duration), + Email: omit.From(email), + InspectionType: omit.From(inspection_type), + Location: omit.From(location), PreferredDateRange: omit.From(preferred_date_range), - PreferredTime: omit.From(preferred_time), - PublicID: omit.From(public_id), - RequestCall: omit.From(request_call), - Severity: omit.From(int16(severity)), - SourceContainer: omit.From(source_container), - SourceDescription: omit.From(source_description), - SourceRoof: omit.From(source_roof), - SourceStagnant: omit.From(source_stagnant), - TimeOfDayDay: omit.From(tod_day), - TimeOfDayEarly: omit.From(tod_early), - TimeOfDayEvening: omit.From(tod_evening), - TimeOfDayNight: omit.From(tod_night), - ReporterAddress: omit.From(address), - ReporterEmail: omit.From(email), - ReporterName: omit.From(name), - ReporterPhone: omit.From(phone), + PreferredTime: omit.From(preferred_time), + PublicID: omit.From(public_id), + RequestCall: omit.From(request_call), + Severity: omit.From(int16(severity)), + SourceContainer: omit.From(source_container), + SourceDescription: omit.From(source_description), + SourceRoof: omit.From(source_roof), + SourceStagnant: omit.From(source_stagnant), + TimeOfDayDay: omit.From(tod_day), + TimeOfDayEarly: omit.From(tod_early), + TimeOfDayEvening: omit.From(tod_evening), + TimeOfDayNight: omit.From(tod_night), + ReporterAddress: omit.From(address), + ReporterEmail: omit.From(email), + ReporterName: omit.From(name), + ReporterPhone: omit.From(phone), } nuisance, err := models.PublicreportNuisances.Insert(&setter).One(r.Context(), db.PGInstance.BobDB) if err != nil { @@ -221,108 +168,6 @@ func postNuisance(w http.ResponseWriter, r *http.Request) { http.Redirect(w, r, fmt.Sprintf("/nuisance-submit-complete?report=%s", public_id), http.StatusFound) } -func postQuick(w http.ResponseWriter, r *http.Request) { - err := r.ParseMultipartForm(32 << 10) // 32 MB buffer - if err != nil { - respondError(w, "Failed to parse form", err, http.StatusBadRequest) - return - } - lat := r.FormValue("latitude") - lng := r.FormValue("longitude") - comments := r.FormValue("comments") - //photos := r.FormValue("photos") - - 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 - } - u, err := GenerateReportID() - if err != nil { - respondError(w, "Failed to create quick report public ID", err, http.StatusInternalServerError) - return - } - c, err := h3utils.GetCell(longitude, latitude, 15) - setter := models.PublicreportQuickSetter{ - Created: omit.From(time.Now()), - Comments: omit.From(comments), - //Location: omitnull.From(fmt.Sprintf("ST_GeometryFromText(Point(%s %s))", longitude, latitude)), - H3cell: omitnull.From(c.String()), - PublicID: omit.From(u), - ReporterEmail: omit.From(""), - ReporterPhone: omit.From(""), - } - quick, err := models.PublicreportQuicks.Insert(&setter).One(r.Context(), db.PGInstance.BobDB) - if err != nil { - respondError(w, "Failed to create database record", err, http.StatusInternalServerError) - return - } - _, err = psql.Update( - um.Table("publicreport.quick"), - um.SetCol("location").To(fmt.Sprintf("ST_GeometryFromText('Point(%f %f)')", longitude, latitude)), - um.Where(psql.Quote("id").EQ(psql.Arg(quick.ID))), - ).Exec(r.Context(), db.PGInstance.BobDB) - if err != nil { - respondError(w, "Failed to insert publicreport", err, http.StatusInternalServerError) - return - } - log.Info().Float64("latitude", latitude).Float64("longitude", longitude).Msg("Got upload") - photoSetters := make([]*models.PublicreportQuickPhotoSetter, 0) - for _, fheaders := range r.MultipartForm.File { - for _, headers := range fheaders { - file, err := headers.Open() - - if err != nil { - respondError(w, "Failed to open header", err, http.StatusInternalServerError) - return - } - - defer file.Close() - - buff := make([]byte, 512) - file.Read(buff) - - file.Seek(0, 0) - contentType := http.DetectContentType(buff) - var sizeBuff bytes.Buffer - fileSize, err := sizeBuff.ReadFrom(file) - if err != nil { - respondError(w, "Failed to read file", err, http.StatusInternalServerError) - return - } - file.Seek(0, 0) - contentBuf := bytes.NewBuffer(nil) - if _, err := io.Copy(contentBuf, file); err != nil { - respondError(w, "Failed to save file", err, http.StatusInternalServerError) - return - } - log.Info().Int64("size", fileSize).Str("filename", headers.Filename).Str("content-type", contentType).Msg("Got an uploaded file") - u, err := uuid.NewUUID() - if err != nil { - respondError(w, "Failed to create quick report photo uuid", err, http.StatusInternalServerError) - continue - } - err = userfile.PublicImageFileContentWrite(u, file) - photoSetters = append(photoSetters, &models.PublicreportQuickPhotoSetter{ - Size: omit.From(fileSize), - Filename: omit.From(headers.Filename), - UUID: omit.From(u), - }) - } - } - err = quick.InsertQuickPhotos(r.Context(), db.PGInstance.BobDB, photoSetters...) - if err != nil { - respondError(w, "Failed to create photo records", err, http.StatusInternalServerError) - return - } - http.Redirect(w, r, fmt.Sprintf("/quick-submit-complete?report=%s", u), http.StatusFound) -} - func postRegisterNotifications(w http.ResponseWriter, r *http.Request) { err := r.ParseForm() if err != nil { diff --git a/public-report/geospatial.go b/public-report/geospatial.go new file mode 100644 index 00000000..7b260909 --- /dev/null +++ b/public-report/geospatial.go @@ -0,0 +1,69 @@ +package publicreport + +import ( + "fmt" + "net/http" + "strconv" + + "github.com/Gleipnir-Technology/nidus-sync/h3utils" + "github.com/rs/zerolog/log" + "github.com/uber/h3-go/v4" +) + +type GeospatialData struct { + Cell h3.Cell + GeometryQuery string + Populated bool +} + +func geospatialFromForm(r *http.Request) (GeospatialData, error) { + lat := r.FormValue("latitude") + lng := r.FormValue("longitude") + accuracy_type := r.FormValue("latlng-accuracy-type") + accuracy_value := r.FormValue("latlng-accuracy-value") + + if lat == "" || lng == "" { + return GeospatialData{Populated: false}, nil + } + latitude, err := strconv.ParseFloat(lat, 64) + if err != nil { + return GeospatialData{Populated: false}, fmt.Errorf("Failed to create parse latitude: %v", err) + } + longitude, err := strconv.ParseFloat(lng, 64) + if err != nil { + return GeospatialData{Populated: false}, fmt.Errorf("Failed to create parse longitude: %v", err) + } + var resolution int + switch accuracy_type { + // These accuracy_type strings come from the Mapbox Geocoding API definition and + // are far from scientific + case "rooftop": + resolution = 14 + case "parcel": + resolution = 13 + case "point": + resolution = 13 + case "interpolated": + resolution = 12 + case "approximate": + resolution = 11 + case "intersection": + resolution = 10 + // This is a special indicator that we got our location from the browser measurements + case "meters": + accuracy_in_meters, err := strconv.ParseFloat(accuracy_value, 64) + if err != nil { + return GeospatialData{Populated: false}, fmt.Errorf("Failed to parse '%s' as an accuracy in meters: %v", accuracy_value, err) + } + resolution = h3utils.MeterAccuracyToH3Resolution(accuracy_in_meters) + default: + log.Warn().Str("accuracy-type", accuracy_type).Msg("unrecognized accuracy type, this indicates either a weird client or misbehaving web page. Defaulting to resolution 13") + resolution = 13 + } + cell, err := h3utils.GetCell(longitude, latitude, resolution) + return GeospatialData{ + Cell: cell, + GeometryQuery: fmt.Sprintf("ST_GeometryFromText('Point(%f %f)')", longitude, latitude), + Populated: true, + }, nil +} diff --git a/public-report/page.go b/public-report/page.go index 8d4a2820..109248e7 100644 --- a/public-report/page.go +++ b/public-report/page.go @@ -17,13 +17,6 @@ type ContextNuisance struct{} type ContextNuisanceSubmitComplete struct { ReportID string } -type ContextPool struct{ - MapboxToken string -} -type ContextQuick struct{} -type ContextQuickSubmitComplete struct { - ReportID string -} type ContextRegisterNotificationsComplete struct { ReportID string } @@ -33,15 +26,12 @@ type ContextStatus struct{} var ( Nuisance = buildTemplate("nuisance", "base") NuisanceSubmitComplete = buildTemplate("nuisance-submit-complete", "base") - Pool = buildTemplate("pool", "base") - Quick = buildTemplate("quick", "base") - QuickSubmitComplete = buildTemplate("quick-submit-complete", "base") RegisterNotificationsComplete = buildTemplate("register-notifications-complete", "base") Root = buildTemplate("root", "base") Status = buildTemplate("status", "base") ) -var components = [...]string{"footer", "location-geocode", "location-geocode-header", "map", "map-header", "photo-upload", "photo-upload-header"} +var components = [...]string{"footer", "location-geocode", "location-geocode-header", "photo-upload", "photo-upload-header"} func buildTemplate(files ...string) *htmlpage.BuiltTemplate { subdir := "public-report" diff --git a/public-report/photo-upload.go b/public-report/photo-upload.go new file mode 100644 index 00000000..58846e09 --- /dev/null +++ b/public-report/photo-upload.go @@ -0,0 +1,64 @@ +package publicreport + +import ( + "bytes" + "fmt" + "io" + "net/http" + + "github.com/Gleipnir-Technology/nidus-sync/userfile" + "github.com/google/uuid" + "github.com/rs/zerolog/log" +) + +type PhotoUpload struct { + Filename string + Size int64 + UUID uuid.UUID +} + +func extractPhotoUploads(r *http.Request) (uploads []PhotoUpload, err error) { + uploads = make([]PhotoUpload, 0) + for _, fheaders := range r.MultipartForm.File { + for _, headers := range fheaders { + file, err := headers.Open() + + if err != nil { + return uploads, fmt.Errorf("Failed to open header: %v", err) + } + + defer file.Close() + + buff := make([]byte, 512) + file.Read(buff) + + file.Seek(0, 0) + contentType := http.DetectContentType(buff) + var sizeBuff bytes.Buffer + fileSize, err := sizeBuff.ReadFrom(file) + if err != nil { + return uploads, fmt.Errorf("Failed to read file: %v", err) + } + file.Seek(0, 0) + contentBuf := bytes.NewBuffer(nil) + if _, err := io.Copy(contentBuf, file); err != nil { + return uploads, fmt.Errorf("Failed to save file: %v", err) + } + log.Info().Int64("size", fileSize).Str("filename", headers.Filename).Str("content-type", contentType).Msg("Got an uploaded file") + u, err := uuid.NewUUID() + if err != nil { + return uploads, fmt.Errorf("Failed to create quick report photo uuid", err) + } + err = userfile.PublicImageFileContentWrite(u, file) + if err != nil { + return uploads, fmt.Errorf("Failed to write image file to disk: %v", err) + } + uploads = append(uploads, PhotoUpload{ + Size: fileSize, + Filename: headers.Filename, + UUID: u, + }) + } + } + return uploads, nil +} diff --git a/public-report/pool.go b/public-report/pool.go new file mode 100644 index 00000000..8954f24e --- /dev/null +++ b/public-report/pool.go @@ -0,0 +1,165 @@ +package publicreport + +import ( + "fmt" + "net/http" + "strconv" + "time" + + "github.com/Gleipnir-Technology/nidus-sync/config" + "github.com/Gleipnir-Technology/nidus-sync/db" + "github.com/Gleipnir-Technology/nidus-sync/db/models" + "github.com/Gleipnir-Technology/nidus-sync/htmlpage" + "github.com/aarondl/opt/omit" + "github.com/rs/zerolog/log" + "github.com/stephenafamo/bob/dialect/psql" + "github.com/stephenafamo/bob/dialect/psql/um" +) + +type ContextPool struct { + MapboxToken string +} +type ContextPoolSubmitComplete struct { + ReportID string +} + +var ( + Pool = buildTemplate("pool", "base") + PoolSubmitComplete = buildTemplate("pool-submit-complete", "base") +) + +func getPool(w http.ResponseWriter, r *http.Request) { + htmlpage.RenderOrError( + w, + Pool, + ContextPool{ + MapboxToken: config.MapboxToken, + }, + ) +} +func getPoolSubmitComplete(w http.ResponseWriter, r *http.Request) { + report := r.URL.Query().Get("report") + htmlpage.RenderOrError( + w, + PoolSubmitComplete, + ContextPoolSubmitComplete{ + ReportID: report, + }, + ) +} +func postPool(w http.ResponseWriter, r *http.Request) { + err := r.ParseMultipartForm(32 << 10) // 32 MB buffer + if err != nil { + respondError(w, "Failed to parse form", err, http.StatusBadRequest) + return + } + access_comments := r.FormValue("access-comments") + access_gate := boolFromForm(r, "access-gate") + access_fence := boolFromForm(r, "access-fence") + access_locked := boolFromForm(r, "access-locked") + access_dog := boolFromForm(r, "access-dog") + access_other := boolFromForm(r, "access-other") + address := r.FormValue("address") + address_country := r.FormValue("address-country") + address_postcode := r.FormValue("address-postcode") + address_place := r.FormValue("address-place") + address_region := r.FormValue("address-region") + address_street := r.FormValue("address-street") + comments := r.FormValue("comments") + has_adult := boolFromForm(r, "has-adult") + has_larvae := boolFromForm(r, "has-larvae") + has_pupae := boolFromForm(r, "has-pupae") + map_zoom_str := r.FormValue("map-zoom") + owner_email := r.FormValue("owner-email") + owner_name := r.FormValue("owner-name") + owner_phone := r.FormValue("owner-phone") + reporter_email := r.FormValue("reporter-email") + reporter_name := r.FormValue("reporter-name") + reporter_phone := r.FormValue("reporter-phone") + subscribe := boolFromForm(r, "subscribe") + + map_zoom, err := strconv.ParseFloat(map_zoom_str, 32) + if err != nil { + respondError(w, "Failed to parse zoom level", err, http.StatusBadRequest) + return + } + public_id, err := GenerateReportID() + if err != nil { + respondError(w, "Failed to create pool report public ID", err, http.StatusInternalServerError) + return + } + + setter := models.PublicreportPoolSetter{ + AccessComments: omit.From(access_comments), + AccessGate: omit.From(access_gate), + AccessFence: omit.From(access_fence), + AccessLocked: omit.From(access_locked), + AccessDog: omit.From(access_dog), + AccessOther: omit.From(access_other), + Address: omit.From(address), + AddressCountry: omit.From(address_country), + AddressPostCode: omit.From(address_postcode), + AddressPlace: omit.From(address_place), + AddressStreet: omit.From(address_street), + AddressRegion: omit.From(address_region), + Comments: omit.From(comments), + Created: omit.From(time.Now()), + //H3cell: add later + HasAdult: omit.From(has_adult), + HasLarvae: omit.From(has_larvae), + HasPupae: omit.From(has_pupae), + //Location: add later + MapZoom: omit.From(map_zoom), + OwnerEmail: omit.From(owner_email), + OwnerName: omit.From(owner_name), + OwnerPhone: omit.From(owner_phone), + PublicID: omit.From(public_id), + ReporterEmail: omit.From(reporter_email), + ReporterName: omit.From(reporter_name), + ReporterPhone: omit.From(reporter_phone), + Subscribe: omit.From(subscribe), + } + pool, err := models.PublicreportPools.Insert(&setter).One(r.Context(), db.PGInstance.BobDB) + if err != nil { + respondError(w, "Failed to create database record", err, http.StatusInternalServerError) + return + } + + geospatial, err := geospatialFromForm(r) + if err != nil { + respondError(w, "Failed to handle geospatial data", err, http.StatusInternalServerError) + return + } + if geospatial.Populated { + _, err = psql.Update( + um.Table("publicreport.pool"), + um.SetCol("h3cell").ToArg(geospatial.Cell), + um.SetCol("location").To(geospatial.GeometryQuery), + um.Where(psql.Quote("id").EQ(psql.Arg(pool.ID))), + ).Exec(r.Context(), db.PGInstance.BobDB) + if err != nil { + respondError(w, "Failed to insert publicreport.pool", err, http.StatusInternalServerError) + return + } + } + log.Info().Int32("id", pool.ID).Str("public_id", pool.PublicID).Msg("Created pool report") + photoSetters := make([]*models.PublicreportPoolPhotoSetter, 0) + uploads, err := extractPhotoUploads(r) + if err != nil { + respondError(w, "Failed to extract photo uploads", err, http.StatusInternalServerError) + return + } + for _, u := range uploads { + photoSetters = append(photoSetters, &models.PublicreportPoolPhotoSetter{ + Filename: omit.From(u.Filename), + Size: omit.From(u.Size), + UUID: omit.From(u.UUID), + }) + } + err = pool.InsertPoolPhotos(r.Context(), db.PGInstance.BobDB, photoSetters...) + if err != nil { + respondError(w, "Failed to create photo records", err, http.StatusInternalServerError) + return + } + http.Redirect(w, r, fmt.Sprintf("/pool-submit-complete?report=%s", public_id), http.StatusFound) +} diff --git a/public-report/quick.go b/public-report/quick.go new file mode 100644 index 00000000..9f38e362 --- /dev/null +++ b/public-report/quick.go @@ -0,0 +1,117 @@ +package publicreport + +import ( + "fmt" + "net/http" + "strconv" + "time" + + "github.com/Gleipnir-Technology/nidus-sync/db" + "github.com/Gleipnir-Technology/nidus-sync/db/models" + "github.com/Gleipnir-Technology/nidus-sync/h3utils" + "github.com/Gleipnir-Technology/nidus-sync/htmlpage" + "github.com/aarondl/opt/omit" + "github.com/aarondl/opt/omitnull" + "github.com/rs/zerolog/log" + "github.com/stephenafamo/bob/dialect/psql" + "github.com/stephenafamo/bob/dialect/psql/um" +) + +type ContextQuick struct{} +type ContextQuickSubmitComplete struct { + ReportID string +} + +var ( + Quick = buildTemplate("quick", "base") + QuickSubmitComplete = buildTemplate("quick-submit-complete", "base") +) + +func getQuick(w http.ResponseWriter, r *http.Request) { + htmlpage.RenderOrError( + w, + Quick, + ContextQuick{}, + ) +} +func getQuickSubmitComplete(w http.ResponseWriter, r *http.Request) { + report := r.URL.Query().Get("report") + htmlpage.RenderOrError( + w, + QuickSubmitComplete, + ContextQuickSubmitComplete{ + ReportID: report, + }, + ) +} +func postQuick(w http.ResponseWriter, r *http.Request) { + err := r.ParseMultipartForm(32 << 10) // 32 MB buffer + if err != nil { + respondError(w, "Failed to parse form", err, http.StatusBadRequest) + return + } + lat := r.FormValue("latitude") + lng := r.FormValue("longitude") + comments := r.FormValue("comments") + //photos := r.FormValue("photos") + + 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 + } + u, err := GenerateReportID() + if err != nil { + respondError(w, "Failed to create quick report public ID", err, http.StatusInternalServerError) + return + } + c, err := h3utils.GetCell(longitude, latitude, 15) + setter := models.PublicreportQuickSetter{ + Created: omit.From(time.Now()), + Comments: omit.From(comments), + //Location: omitnull.From(fmt.Sprintf("ST_GeometryFromText(Point(%s %s))", longitude, latitude)), + H3cell: omitnull.From(c.String()), + PublicID: omit.From(u), + ReporterEmail: omit.From(""), + ReporterPhone: omit.From(""), + } + quick, err := models.PublicreportQuicks.Insert(&setter).One(r.Context(), db.PGInstance.BobDB) + if err != nil { + respondError(w, "Failed to create database record", err, http.StatusInternalServerError) + return + } + _, err = psql.Update( + um.Table("publicreport.quick"), + um.SetCol("location").To(fmt.Sprintf("ST_GeometryFromText('Point(%f %f)')", longitude, latitude)), + um.Where(psql.Quote("id").EQ(psql.Arg(quick.ID))), + ).Exec(r.Context(), db.PGInstance.BobDB) + if err != nil { + respondError(w, "Failed to insert publicreport", err, http.StatusInternalServerError) + return + } + log.Info().Float64("latitude", latitude).Float64("longitude", longitude).Msg("Got upload") + photoSetters := make([]*models.PublicreportQuickPhotoSetter, 0) + uploads, err := extractPhotoUploads(r) + if err != nil { + respondError(w, "Failed to extract photo uploads", err, http.StatusInternalServerError) + return + } + for _, u := range uploads { + photoSetters = append(photoSetters, &models.PublicreportQuickPhotoSetter{ + Filename: omit.From(u.Filename), + Size: omit.From(u.Size), + UUID: omit.From(u.UUID), + }) + } + err = quick.InsertQuickPhotos(r.Context(), db.PGInstance.BobDB, photoSetters...) + if err != nil { + respondError(w, "Failed to create photo records", err, http.StatusInternalServerError) + return + } + http.Redirect(w, r, fmt.Sprintf("/quick-submit-complete?report=%s", u), http.StatusFound) +} diff --git a/public-report/routes.go b/public-report/routes.go new file mode 100644 index 00000000..3bdd6b32 --- /dev/null +++ b/public-report/routes.go @@ -0,0 +1,28 @@ +package publicreport + +import ( + "net/http" + + "github.com/Gleipnir-Technology/nidus-sync/htmlpage" + "github.com/go-chi/chi/v5" +) + +func Router() chi.Router { + r := chi.NewRouter() + r.Get("/", getRoot) + r.Get("/nuisance", getNuisance) + r.Post("/nuisance-submit", postNuisance) + r.Get("/nuisance-submit-complete", getNuisanceSubmitComplete) + r.Get("/pool", getPool) + r.Post("/pool-submit", postPool) + r.Get("/pool-submit-complete", getPoolSubmitComplete) + r.Get("/quick", getQuick) + r.Post("/quick-submit", postQuick) + r.Get("/quick-submit-complete", getQuickSubmitComplete) + r.Post("/register-notifications", postRegisterNotifications) + r.Get("/register-notifications-complete", getRegisterNotificationsComplete) + r.Get("/status", getStatus) + localFS := http.Dir("./static") + htmlpage.FileServer(r, "/static", localFS, EmbeddedStaticFS, "static") + return r +} diff --git a/public-report/template/component/location-geocode-header.html b/public-report/template/component/location-geocode-header.html index 82a40c24..a392eba8 100644 --- a/public-report/template/component/location-geocode-header.html +++ b/public-report/template/component/location-geocode-header.html @@ -66,12 +66,16 @@ function displaySuggestions(suggestions) { } // Handle click on a suggestion item.addEventListener('click', function() { - addressInput.value = suggestion.properties.name || suggestion.properties.full_address; + // Hide the suggestions container + setLocationInputs(suggestion); suggestionsContainer.classList.add('d-none'); - - // Display the selected location details displaySelectedLocation(suggestion); - setMapMarker(suggestion.geometry.coordinates); + const locationSelected = new CustomEvent("locationselected", { + detail: { + coordinates: suggestion.geometry.coordinates, + }, + }); + suggestionsContainer.dispatchEvent(locationSelected); }); suggestionsContainer.appendChild(item); @@ -155,18 +159,45 @@ function onAddressInput() { }, 300); } +function setLocationInputs(suggestion) { + let address = document.getElementById('address'); + let country = document.getElementById('address-country'); + let latitude = document.getElementById('latitude'); + let longitude = document.getElementById('longitude'); + let latlngAccuracyType = document.getElementById('latlng-accuracy-type'); + let postcode = document.getElementById('address-postcode'); + let place = document.getElementById('address-place'); + let region = document.getElementById('address-region'); + let street = document.getElementById('address-street'); + + // Extract context data from properties + const props = suggestion.properties; + const context = props.context || {}; + + // Populate structured fields + address.value = props.full_address; + country.value = context.country.name; + latitude.value = props.coordinates.latitude; + longitude.value = props.coordinates.longitude; + latlngAccuracyType.value = props.coordinates.accuracy; + postcode.value = context.postcode.name; + place.value = context.place.name; + region.value = context.region.name; + street.value = context.country.name; +} + document.addEventListener('DOMContentLoaded', function() { - const addressInput = document.getElementById('addressInput'); + const address = document.getElementById('address'); const suggestionsContainer = document.getElementById('suggestions'); const locationDetails = document.getElementById('locationDetails'); // Listen for input changes - addressInput.addEventListener('input', onAddressInput); + address.addEventListener('input', onAddressInput); // Close suggestions when clicking outside document.addEventListener('click', function(event) { - if (!addressInput.contains(event.target) && !suggestionsContainer.contains(event.target)) { + if (!address.contains(event.target) && !suggestionsContainer.contains(event.target)) { suggestionsContainer.classList.add('d-none'); } }); diff --git a/public-report/template/component/location-geocode.html b/public-report/template/component/location-geocode.html index d73ecd04..3198e9f9 100644 --- a/public-report/template/component/location-geocode.html +++ b/public-report/template/component/location-geocode.html @@ -1,9 +1,18 @@ {{define "location-geocode"}} + + + + + + + + + +
-

Address Search

-
diff --git a/public-report/template/component/map-header.html b/public-report/template/component/map-header.html index 740e17fa..26600df6 100644 --- a/public-report/template/component/map-header.html +++ b/public-report/template/component/map-header.html @@ -1,144 +1,2 @@ {{define "map-header"}} - - - - {{end}} diff --git a/public-report/template/component/photo-upload.html b/public-report/template/component/photo-upload.html index 29499e65..d9fe4ecd 100644 --- a/public-report/template/component/photo-upload.html +++ b/public-report/template/component/photo-upload.html @@ -1,5 +1,4 @@ {{define "photo-upload"}} -
diff --git a/public-report/template/pool-submit-complete.html b/public-report/template/pool-submit-complete.html new file mode 100644 index 00000000..700d6791 --- /dev/null +++ b/public-report/template/pool-submit-complete.html @@ -0,0 +1,115 @@ +{{template "base.html" .}} + +{{define "title"}}Nuisance Submission Complete{{end}} +{{define "extraheader"}} + + +{{end}} +{{define "content"}} +
+
+
+ +
+
+

+ + + + Pool Report Complete +

+
+
+
+
+ + + +
+

Thank You!

+

Your report has been successfully submitted.

+
+ Report ID: + {{.ReportID}} +
+
+ +
+ + +
+
+ + + + + What to Expect +
+
    +
  • + + + + + A confirmation message has been sent to your contact information. +
  • +
  • + + + + + + You will receive updates when: +
      +
    • Your report is assigned to a specialist
    • +
    • A site visit is scheduled
    • +
    • Treatment or remediation is completed
    • +
    • The case is resolved
    • +
    +
  • +
  • + + + + You can check your report status anytime using your Report ID. +
  • +
+
+ + + +
+
+ + +
+
+
+ + + + + Need Help? +
+

If you need to update your contact information or have questions about your report, please contact our Mosquito Control Unit at (123) 456-7890 or mosquito@example.gov and reference your Report ID.

+
+
+
+
+
+{{end}} diff --git a/public-report/template/pool.html b/public-report/template/pool.html index 099cc6ca..8d9f96bc 100644 --- a/public-report/template/pool.html +++ b/public-report/template/pool.html @@ -3,7 +3,8 @@ {{define "title"}}Green Pool{{end}} {{define "extraheader"}} {{template "location-geocode-header" .}} -{{template "map-header" .}} + + {{template "photo-upload-header"}} + {{end}} {{define "content"}} @@ -77,7 +346,7 @@
-
+
@@ -86,8 +355,9 @@ optional

Photos help us identify the severity of the issue and may contain location data that can help us find the source.

- - {{template "photo-upload"}} +
+ {{template "photo-upload"}} +
@@ -119,6 +389,7 @@
+
@@ -132,8 +403,8 @@
- + @@ -145,20 +416,20 @@
- +
- +
- -
@@ -177,8 +448,8 @@
- - + +
@@ -188,28 +459,28 @@
- +
- +
- - + +
- +
- - + +
@@ -229,16 +500,16 @@
Property Owner Information (if known)
- - + +
- - + +
- - + +
@@ -246,21 +517,21 @@
Your Contact Information (for updates)
- - + +
- - + +
- - + +
- -
@@ -279,8 +550,8 @@
- - + +