Split out ability to upload flyover data from pool uploads

Tons of changes here, all in the name of quickly getting to where I can
create test compliance letters.
This commit is contained in:
Eli Ribble 2026-03-02 18:49:02 +00:00
parent 9939434cb3
commit ff2ec0ad14
No known key found for this signature in database
38 changed files with 4204 additions and 233 deletions

View file

@ -5,14 +5,17 @@ import (
"fmt"
"sync"
"github.com/Gleipnir-Technology/bob"
"github.com/Gleipnir-Technology/bob/dialect/psql"
"github.com/Gleipnir-Technology/bob/dialect/psql/sm"
commsemail "github.com/Gleipnir-Technology/nidus-sync/comms/email"
"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/platform/email"
"github.com/Gleipnir-Technology/nidus-sync/platform/text"
"github.com/rs/zerolog/log"
"github.com/stephenafamo/scan"
)
var waitGroup sync.WaitGroup
@ -20,10 +23,10 @@ var waitGroup sync.WaitGroup
func Start(ctx context.Context) {
newOAuthTokenChannel = make(chan struct{}, 10)
channelJobAudio = make(chan jobAudio, 100) // Buffered channel to prevent blocking
channelJobImportCSVPool = make(chan jobImportCSVPool, 100) // Buffered channel to prevent blocking
channelJobEmail = make(chan email.Job, 100) // Buffered channel to prevent blocking
channelJobText = make(chan text.Job, 100) // Buffered channel to prevent blocking
channelJobAudio = make(chan jobAudio, 100) // Buffered channel to prevent blocking
channelJobImportCSV = make(chan jobImportCSV, 100) // Buffered channel to prevent blocking
channelJobEmail = make(chan email.Job, 100) // Buffered channel to prevent blocking
channelJobText = make(chan text.Job, 100) // Buffered channel to prevent blocking
waitGroup.Add(1)
go func() {
@ -46,7 +49,7 @@ func Start(ctx context.Context) {
waitGroup.Add(1)
go func() {
defer waitGroup.Done()
startWorkerCSV(ctx, channelJobImportCSVPool)
startWorkerCSV(ctx, channelJobImportCSV)
}()
waitGroup.Add(1)
@ -73,21 +76,33 @@ func WaitForExit() {
}
func addWaitingJobs(ctx context.Context) error {
rows, err := models.FileuploadFiles.Query(
models.SelectWhere.FileuploadFiles.Status.EQ(
enums.FileuploadFilestatustypeUploaded,
type Row_ struct {
ID int32 `db:"id"`
Type enums.FileuploadCsvtype `db:"type"`
}
rows, err := bob.All(ctx, db.PGInstance.BobDB, psql.Select(
sm.Columns(
"file.id AS id",
"csv.type_ AS type",
),
).All(ctx, db.PGInstance.BobDB)
sm.From("fileupload.file").As("file"),
sm.InnerJoin("fileupload.csv").As("csv").OnEQ(psql.Raw("file.id"), psql.Raw("csv.file_id")),
sm.Where(
psql.Raw("file.status").EQ(psql.Arg(enums.FileuploadFilestatustypeUploaded)),
),
), scan.StructMapper[Row_]())
if err != nil {
return fmt.Errorf("Failed to query file uploads: %w", err)
}
for _, row := range rows {
report_id := row.ID
job := jobImportCSVPool{
job := jobImportCSV{
fileID: report_id,
type_: row.Type,
}
select {
case channelJobImportCSVPool <- job:
case channelJobImportCSV <- job:
log.Info().Int32("report_id", report_id).Msg("CSV upload job queued")
default:
log.Warn().Int32("report_id", report_id).Msg("CSV upload job failed to queue, channel full")

View file

@ -4,34 +4,36 @@ import (
"context"
//"fmt"
"github.com/Gleipnir-Technology/nidus-sync/db/enums"
"github.com/Gleipnir-Technology/nidus-sync/platform/csv"
//"github.com/Gleipnir-Technology/nidus-sync/userfile"
//"github.com/google/uuid"
"github.com/rs/zerolog/log"
)
// represents a job to import a pool CSV file
type jobImportCSVPool struct {
type jobImportCSV struct {
fileID int32
type_ enums.FileuploadCsvtype
}
var channelJobImportCSVPool chan jobImportCSVPool
var channelJobImportCSV chan jobImportCSV
func ProcessUpload(file_id int32) {
enqueueUploadJob(jobImportCSVPool{
func ProcessUpload(file_id int32, t enums.FileuploadCsvtype) {
enqueueUploadJob(jobImportCSV{
fileID: file_id,
type_: t,
})
}
func enqueueUploadJob(job jobImportCSVPool) {
func enqueueUploadJob(job jobImportCSV) {
select {
case channelJobImportCSVPool <- job:
case channelJobImportCSV <- job:
log.Info().Int32("file_id", job.fileID).Msg("Enqueued csv job")
default:
log.Warn().Int32("file_id", job.fileID).Msg("csv channel is full, dropping job")
}
}
func startWorkerCSV(ctx context.Context, channelJobImport chan jobImportCSVPool) {
func startWorkerCSV(ctx context.Context, channelJobImport chan jobImportCSV) {
go func() {
for {
select {
@ -40,7 +42,7 @@ func startWorkerCSV(ctx context.Context, channelJobImport chan jobImportCSVPool)
return
case job := <-channelJobImport:
log.Info().Int32("id", job.fileID).Msg("Processing CSV job")
err := csv.ProcessJob(ctx, job.fileID)
err := csv.ProcessJob(ctx, job.fileID, job.type_)
if err != nil {
log.Error().Err(err).Int32("id", job.fileID).Msg("Error processing CSV file")
}

View file

@ -0,0 +1,17 @@
// Code generated by BobGen psql v0.42.5. DO NOT EDIT.
// This file is meant to be re-generated in place and/or deleted at any time.
package dberrors
var FileuploadFlyoverAerialServiceErrors = &fileuploadFlyoverAerialServiceErrors{
ErrUniqueFlyoverAerialServicePkey: &UniqueConstraintError{
schema: "fileupload",
table: "flyover_aerial_service",
columns: []string{"id"},
s: "flyover_aerial_service_pkey",
},
}
type fileuploadFlyoverAerialServiceErrors struct {
ErrUniqueFlyoverAerialServicePkey *UniqueConstraintError
}

View file

@ -0,0 +1,217 @@
// Code generated by BobGen psql v0.42.5. DO NOT EDIT.
// This file is meant to be re-generated in place and/or deleted at any time.
package dbinfo
import "github.com/aarondl/opt/null"
var FileuploadFlyoverAerialServices = Table[
fileuploadFlyoverAerialServiceColumns,
fileuploadFlyoverAerialServiceIndexes,
fileuploadFlyoverAerialServiceForeignKeys,
fileuploadFlyoverAerialServiceUniques,
fileuploadFlyoverAerialServiceChecks,
]{
Schema: "fileupload",
Name: "flyover_aerial_service",
Columns: fileuploadFlyoverAerialServiceColumns{
Committed: column{
Name: "committed",
DBType: "boolean",
Default: "",
Comment: "",
Nullable: false,
Generated: false,
AutoIncr: false,
},
Condition: column{
Name: "condition",
DBType: "fileupload.poolconditiontype",
Default: "",
Comment: "",
Nullable: false,
Generated: false,
AutoIncr: false,
},
Created: column{
Name: "created",
DBType: "timestamp without time zone",
Default: "",
Comment: "",
Nullable: false,
Generated: false,
AutoIncr: false,
},
CreatorID: column{
Name: "creator_id",
DBType: "integer",
Default: "",
Comment: "",
Nullable: false,
Generated: false,
AutoIncr: false,
},
CSVFile: column{
Name: "csv_file",
DBType: "integer",
Default: "",
Comment: "",
Nullable: false,
Generated: false,
AutoIncr: false,
},
Deleted: column{
Name: "deleted",
DBType: "timestamp without time zone",
Default: "NULL",
Comment: "",
Nullable: true,
Generated: false,
AutoIncr: false,
},
Geom: column{
Name: "geom",
DBType: "geometry",
Default: "NULL",
Comment: "",
Nullable: true,
Generated: false,
AutoIncr: false,
},
H3cell: column{
Name: "h3cell",
DBType: "h3index",
Default: "NULL",
Comment: "",
Nullable: true,
Generated: false,
AutoIncr: false,
},
ID: column{
Name: "id",
DBType: "integer",
Default: "nextval('fileupload.flyover_aerial_service_id_seq'::regclass)",
Comment: "",
Nullable: false,
Generated: false,
AutoIncr: false,
},
OrganizationID: column{
Name: "organization_id",
DBType: "integer",
Default: "",
Comment: "",
Nullable: false,
Generated: false,
AutoIncr: false,
},
},
Indexes: fileuploadFlyoverAerialServiceIndexes{
FlyoverAerialServicePkey: index{
Type: "btree",
Name: "flyover_aerial_service_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: "flyover_aerial_service_pkey",
Columns: []string{"id"},
Comment: "",
},
ForeignKeys: fileuploadFlyoverAerialServiceForeignKeys{
FileuploadFlyoverAerialServiceFlyoverAerialServiceCreatorIDFkey: foreignKey{
constraint: constraint{
Name: "fileupload.flyover_aerial_service.flyover_aerial_service_creator_id_fkey",
Columns: []string{"creator_id"},
Comment: "",
},
ForeignTable: "user_",
ForeignColumns: []string{"id"},
},
FileuploadFlyoverAerialServiceFlyoverAerialServiceCSVFileFkey: foreignKey{
constraint: constraint{
Name: "fileupload.flyover_aerial_service.flyover_aerial_service_csv_file_fkey",
Columns: []string{"csv_file"},
Comment: "",
},
ForeignTable: "fileupload.csv",
ForeignColumns: []string{"file_id"},
},
FileuploadFlyoverAerialServiceFlyoverAerialServiceOrganizationIDFkey: foreignKey{
constraint: constraint{
Name: "fileupload.flyover_aerial_service.flyover_aerial_service_organization_id_fkey",
Columns: []string{"organization_id"},
Comment: "",
},
ForeignTable: "organization",
ForeignColumns: []string{"id"},
},
},
Comment: "",
}
type fileuploadFlyoverAerialServiceColumns struct {
Committed column
Condition column
Created column
CreatorID column
CSVFile column
Deleted column
Geom column
H3cell column
ID column
OrganizationID column
}
func (c fileuploadFlyoverAerialServiceColumns) AsSlice() []column {
return []column{
c.Committed, c.Condition, c.Created, c.CreatorID, c.CSVFile, c.Deleted, c.Geom, c.H3cell, c.ID, c.OrganizationID,
}
}
type fileuploadFlyoverAerialServiceIndexes struct {
FlyoverAerialServicePkey index
}
func (i fileuploadFlyoverAerialServiceIndexes) AsSlice() []index {
return []index{
i.FlyoverAerialServicePkey,
}
}
type fileuploadFlyoverAerialServiceForeignKeys struct {
FileuploadFlyoverAerialServiceFlyoverAerialServiceCreatorIDFkey foreignKey
FileuploadFlyoverAerialServiceFlyoverAerialServiceCSVFileFkey foreignKey
FileuploadFlyoverAerialServiceFlyoverAerialServiceOrganizationIDFkey foreignKey
}
func (f fileuploadFlyoverAerialServiceForeignKeys) AsSlice() []foreignKey {
return []foreignKey{
f.FileuploadFlyoverAerialServiceFlyoverAerialServiceCreatorIDFkey, f.FileuploadFlyoverAerialServiceFlyoverAerialServiceCSVFileFkey, f.FileuploadFlyoverAerialServiceFlyoverAerialServiceOrganizationIDFkey,
}
}
type fileuploadFlyoverAerialServiceUniques struct{}
func (u fileuploadFlyoverAerialServiceUniques) AsSlice() []constraint {
return []constraint{}
}
type fileuploadFlyoverAerialServiceChecks struct{}
func (c fileuploadFlyoverAerialServiceChecks) AsSlice() []check {
return []check{}
}

View file

@ -986,11 +986,13 @@ func (e *Countrytype) Scan(value any) error {
// Enum values for FileuploadCsvtype
const (
FileuploadCsvtypePoollist FileuploadCsvtype = "PoolList"
FileuploadCsvtypeFlyover FileuploadCsvtype = "Flyover"
)
func AllFileuploadCsvtype() []FileuploadCsvtype {
return []FileuploadCsvtype{
FileuploadCsvtypePoollist,
FileuploadCsvtypeFlyover,
}
}
@ -1002,7 +1004,8 @@ func (e FileuploadCsvtype) String() string {
func (e FileuploadCsvtype) Valid() bool {
switch e {
case FileuploadCsvtypePoollist:
case FileuploadCsvtypePoollist,
FileuploadCsvtypeFlyover:
return true
default:
return false

View file

@ -236,10 +236,11 @@ var (
fieldseekerSyncRelOrganizationCtx = newContextual[bool]("fieldseeker_sync.organization.fieldseeker_sync.fieldseeker_sync_organization_id_fkey")
// Relationship Contexts for fileupload.csv
fileuploadCSVWithParentsCascadingCtx = newContextual[bool]("fileuploadCSVWithParentsCascading")
fileuploadCSVRelFileCtx = newContextual[bool]("fileupload.csv.fileupload.file.fileupload.csv.csv_file_id_fkey")
fileuploadCSVRelCSVFileErrorCSVSCtx = newContextual[bool]("fileupload.csv.fileupload.error_csv.fileupload.error_csv.error_csv_csv_file_id_fkey")
fileuploadCSVRelCSVFilePoolsCtx = newContextual[bool]("fileupload.csv.fileupload.pool.fileupload.pool.pool_csv_file_fkey")
fileuploadCSVWithParentsCascadingCtx = newContextual[bool]("fileuploadCSVWithParentsCascading")
fileuploadCSVRelFileCtx = newContextual[bool]("fileupload.csv.fileupload.file.fileupload.csv.csv_file_id_fkey")
fileuploadCSVRelCSVFileErrorCSVSCtx = newContextual[bool]("fileupload.csv.fileupload.error_csv.fileupload.error_csv.error_csv_csv_file_id_fkey")
fileuploadCSVRelCSVFileFlyoverAerialServicesCtx = newContextual[bool]("fileupload.csv.fileupload.flyover_aerial_service.fileupload.flyover_aerial_service.flyover_aerial_service_csv_file_fkey")
fileuploadCSVRelCSVFilePoolsCtx = newContextual[bool]("fileupload.csv.fileupload.pool.fileupload.pool.pool_csv_file_fkey")
// Relationship Contexts for fileupload.error_csv
fileuploadErrorCSVWithParentsCascadingCtx = newContextual[bool]("fileuploadErrorCSVWithParentsCascading")
@ -257,6 +258,12 @@ var (
fileuploadFileRelOrganizationCtx = newContextual[bool]("fileupload.file.organization.fileupload.file.file_organization_id_fkey")
fileuploadFileRelSitesCtx = newContextual[bool]("fileupload.file.site.site.site_file_id_fkey")
// Relationship Contexts for fileupload.flyover_aerial_service
fileuploadFlyoverAerialServiceWithParentsCascadingCtx = newContextual[bool]("fileuploadFlyoverAerialServiceWithParentsCascading")
fileuploadFlyoverAerialServiceRelCreatorUserCtx = newContextual[bool]("fileupload.flyover_aerial_service.user_.fileupload.flyover_aerial_service.flyover_aerial_service_creator_id_fkey")
fileuploadFlyoverAerialServiceRelCSVFileCSVCtx = newContextual[bool]("fileupload.csv.fileupload.flyover_aerial_service.fileupload.flyover_aerial_service.flyover_aerial_service_csv_file_fkey")
fileuploadFlyoverAerialServiceRelOrganizationCtx = newContextual[bool]("fileupload.flyover_aerial_service.organization.fileupload.flyover_aerial_service.flyover_aerial_service_organization_id_fkey")
// Relationship Contexts for fileupload.pool
fileuploadPoolWithParentsCascadingCtx = newContextual[bool]("fileuploadPoolWithParentsCascading")
fileuploadPoolRelCreatorUserCtx = newContextual[bool]("fileupload.pool.user_.fileupload.pool.pool_creator_id_fkey")
@ -350,6 +357,7 @@ var (
organizationRelZones2sCtx = newContextual[bool]("fieldseeker.zones2.organization.fieldseeker.zones2.zones2_organization_id_fkey")
organizationRelFieldseekerSyncsCtx = newContextual[bool]("fieldseeker_sync.organization.fieldseeker_sync.fieldseeker_sync_organization_id_fkey")
organizationRelFilesCtx = newContextual[bool]("fileupload.file.organization.fileupload.file.file_organization_id_fkey")
organizationRelFlyoverAerialServicesCtx = newContextual[bool]("fileupload.flyover_aerial_service.organization.fileupload.flyover_aerial_service.flyover_aerial_service_organization_id_fkey")
organizationRelPoolsCtx = newContextual[bool]("fileupload.pool.organization.fileupload.pool.pool_organization_id_fkey")
organizationRelH3AggregationsCtx = newContextual[bool]("h3_aggregation.organization.h3_aggregation.h3_aggregation_organization_id_fkey")
organizationRelNoteAudiosCtx = newContextual[bool]("note_audio.organization.note_audio.note_audio_organization_id_fkey")
@ -481,6 +489,7 @@ var (
userRelPublicUserUserCtx = newContextual[bool]("arcgis.user_.user_.arcgis.user_.user__public_user_id_fkey")
userRelCreatorComplianceReportRequestsCtx = newContextual[bool]("compliance_report_request.user_.compliance_report_request.compliance_report_request_creator_fkey")
userRelCreatorFilesCtx = newContextual[bool]("fileupload.file.user_.fileupload.file.file_creator_id_fkey")
userRelCreatorFlyoverAerialServicesCtx = newContextual[bool]("fileupload.flyover_aerial_service.user_.fileupload.flyover_aerial_service.flyover_aerial_service_creator_id_fkey")
userRelFileuploadPoolCtx = newContextual[bool]("fileupload.pool.user_.fileupload.pool.pool_creator_id_fkey")
userRelCreatorNoteAudiosCtx = newContextual[bool]("note_audio.user_.note_audio.note_audio_creator_id_fkey")
userRelDeletorNoteAudiosCtx = newContextual[bool]("note_audio.user_.note_audio.note_audio_deletor_id_fkey")

View file

@ -72,6 +72,7 @@ type Factory struct {
baseFileuploadErrorCSVMods FileuploadErrorCSVModSlice
baseFileuploadErrorFileMods FileuploadErrorFileModSlice
baseFileuploadFileMods FileuploadFileModSlice
baseFileuploadFlyoverAerialServiceMods FileuploadFlyoverAerialServiceModSlice
baseFileuploadPoolMods FileuploadPoolModSlice
baseGeographyColumnMods GeographyColumnModSlice
baseGeometryColumnMods GeometryColumnModSlice
@ -2706,6 +2707,9 @@ func (f *Factory) FromExistingFileuploadCSV(m *models.FileuploadCSV) *Fileupload
if len(m.R.CSVFileErrorCSVS) > 0 {
FileuploadCSVMods.AddExistingCSVFileErrorCSVS(m.R.CSVFileErrorCSVS...).Apply(ctx, o)
}
if len(m.R.CSVFileFlyoverAerialServices) > 0 {
FileuploadCSVMods.AddExistingCSVFileFlyoverAerialServices(m.R.CSVFileFlyoverAerialServices...).Apply(ctx, o)
}
if len(m.R.CSVFilePools) > 0 {
FileuploadCSVMods.AddExistingCSVFilePools(m.R.CSVFilePools...).Apply(ctx, o)
}
@ -2827,6 +2831,50 @@ func (f *Factory) FromExistingFileuploadFile(m *models.FileuploadFile) *Fileuplo
return o
}
func (f *Factory) NewFileuploadFlyoverAerialService(mods ...FileuploadFlyoverAerialServiceMod) *FileuploadFlyoverAerialServiceTemplate {
return f.NewFileuploadFlyoverAerialServiceWithContext(context.Background(), mods...)
}
func (f *Factory) NewFileuploadFlyoverAerialServiceWithContext(ctx context.Context, mods ...FileuploadFlyoverAerialServiceMod) *FileuploadFlyoverAerialServiceTemplate {
o := &FileuploadFlyoverAerialServiceTemplate{f: f}
if f != nil {
f.baseFileuploadFlyoverAerialServiceMods.Apply(ctx, o)
}
FileuploadFlyoverAerialServiceModSlice(mods).Apply(ctx, o)
return o
}
func (f *Factory) FromExistingFileuploadFlyoverAerialService(m *models.FileuploadFlyoverAerialService) *FileuploadFlyoverAerialServiceTemplate {
o := &FileuploadFlyoverAerialServiceTemplate{f: f, alreadyPersisted: true}
o.Committed = func() bool { return m.Committed }
o.Condition = func() enums.FileuploadPoolconditiontype { return m.Condition }
o.Created = func() time.Time { return m.Created }
o.CreatorID = func() int32 { return m.CreatorID }
o.CSVFile = func() int32 { return m.CSVFile }
o.Deleted = func() null.Val[time.Time] { return m.Deleted }
o.Geom = func() null.Val[string] { return m.Geom }
o.H3cell = func() null.Val[string] { return m.H3cell }
o.ID = func() int32 { return m.ID }
o.OrganizationID = func() int32 { return m.OrganizationID }
ctx := context.Background()
if m.R.CreatorUser != nil {
FileuploadFlyoverAerialServiceMods.WithExistingCreatorUser(m.R.CreatorUser).Apply(ctx, o)
}
if m.R.CSVFileCSV != nil {
FileuploadFlyoverAerialServiceMods.WithExistingCSVFileCSV(m.R.CSVFileCSV).Apply(ctx, o)
}
if m.R.Organization != nil {
FileuploadFlyoverAerialServiceMods.WithExistingOrganization(m.R.Organization).Apply(ctx, o)
}
return o
}
func (f *Factory) NewFileuploadPool(mods ...FileuploadPoolMod) *FileuploadPoolTemplate {
return f.NewFileuploadPoolWithContext(context.Background(), mods...)
}
@ -3430,6 +3478,9 @@ func (f *Factory) FromExistingOrganization(m *models.Organization) *Organization
if len(m.R.Files) > 0 {
OrganizationMods.AddExistingFiles(m.R.Files...).Apply(ctx, o)
}
if len(m.R.FlyoverAerialServices) > 0 {
OrganizationMods.AddExistingFlyoverAerialServices(m.R.FlyoverAerialServices...).Apply(ctx, o)
}
if len(m.R.Pools) > 0 {
OrganizationMods.AddExistingPools(m.R.Pools...).Apply(ctx, o)
}
@ -4404,6 +4455,9 @@ func (f *Factory) FromExistingUser(m *models.User) *UserTemplate {
if len(m.R.CreatorFiles) > 0 {
UserMods.AddExistingCreatorFiles(m.R.CreatorFiles...).Apply(ctx, o)
}
if len(m.R.CreatorFlyoverAerialServices) > 0 {
UserMods.AddExistingCreatorFlyoverAerialServices(m.R.CreatorFlyoverAerialServices...).Apply(ctx, o)
}
if len(m.R.FileuploadPool) > 0 {
UserMods.AddExistingFileuploadPool(m.R.FileuploadPool...).Apply(ctx, o)
}
@ -4862,6 +4916,14 @@ func (f *Factory) AddBaseFileuploadFileMod(mods ...FileuploadFileMod) {
f.baseFileuploadFileMods = append(f.baseFileuploadFileMods, mods...)
}
func (f *Factory) ClearBaseFileuploadFlyoverAerialServiceMods() {
f.baseFileuploadFlyoverAerialServiceMods = nil
}
func (f *Factory) AddBaseFileuploadFlyoverAerialServiceMod(mods ...FileuploadFlyoverAerialServiceMod) {
f.baseFileuploadFlyoverAerialServiceMods = append(f.baseFileuploadFlyoverAerialServiceMods, mods...)
}
func (f *Factory) ClearBaseFileuploadPoolMods() {
f.baseFileuploadPoolMods = nil
}

View file

@ -50,9 +50,10 @@ type FileuploadCSVTemplate struct {
}
type fileuploadCSVR struct {
File *fileuploadCSVRFileR
CSVFileErrorCSVS []*fileuploadCSVRCSVFileErrorCSVSR
CSVFilePools []*fileuploadCSVRCSVFilePoolsR
File *fileuploadCSVRFileR
CSVFileErrorCSVS []*fileuploadCSVRCSVFileErrorCSVSR
CSVFileFlyoverAerialServices []*fileuploadCSVRCSVFileFlyoverAerialServicesR
CSVFilePools []*fileuploadCSVRCSVFilePoolsR
}
type fileuploadCSVRFileR struct {
@ -62,6 +63,10 @@ type fileuploadCSVRCSVFileErrorCSVSR struct {
number int
o *FileuploadErrorCSVTemplate
}
type fileuploadCSVRCSVFileFlyoverAerialServicesR struct {
number int
o *FileuploadFlyoverAerialServiceTemplate
}
type fileuploadCSVRCSVFilePoolsR struct {
number int
o *FileuploadPoolTemplate
@ -97,6 +102,19 @@ func (t FileuploadCSVTemplate) setModelRels(o *models.FileuploadCSV) {
o.R.CSVFileErrorCSVS = rel
}
if t.r.CSVFileFlyoverAerialServices != nil {
rel := models.FileuploadFlyoverAerialServiceSlice{}
for _, r := range t.r.CSVFileFlyoverAerialServices {
related := r.o.BuildMany(r.number)
for _, rel := range related {
rel.CSVFile = o.FileID // h2
rel.R.CSVFileCSV = o
}
rel = append(rel, related...)
}
o.R.CSVFileFlyoverAerialServices = rel
}
if t.r.CSVFilePools != nil {
rel := models.FileuploadPoolSlice{}
for _, r := range t.r.CSVFilePools {
@ -226,6 +244,26 @@ func (o *FileuploadCSVTemplate) insertOptRels(ctx context.Context, exec bob.Exec
}
}
isCSVFileFlyoverAerialServicesDone, _ := fileuploadCSVRelCSVFileFlyoverAerialServicesCtx.Value(ctx)
if !isCSVFileFlyoverAerialServicesDone && o.r.CSVFileFlyoverAerialServices != nil {
ctx = fileuploadCSVRelCSVFileFlyoverAerialServicesCtx.WithValue(ctx, true)
for _, r := range o.r.CSVFileFlyoverAerialServices {
if r.o.alreadyPersisted {
m.R.CSVFileFlyoverAerialServices = append(m.R.CSVFileFlyoverAerialServices, r.o.Build())
} else {
rel2, err := r.o.CreateMany(ctx, exec, r.number)
if err != nil {
return err
}
err = m.AttachCSVFileFlyoverAerialServices(ctx, exec, rel2...)
if err != nil {
return err
}
}
}
}
isCSVFilePoolsDone, _ := fileuploadCSVRelCSVFilePoolsCtx.Value(ctx)
if !isCSVFilePoolsDone && o.r.CSVFilePools != nil {
ctx = fileuploadCSVRelCSVFilePoolsCtx.WithValue(ctx, true)
@ -233,12 +271,12 @@ func (o *FileuploadCSVTemplate) insertOptRels(ctx context.Context, exec bob.Exec
if r.o.alreadyPersisted {
m.R.CSVFilePools = append(m.R.CSVFilePools, r.o.Build())
} else {
rel2, err := r.o.CreateMany(ctx, exec, r.number)
rel3, err := r.o.CreateMany(ctx, exec, r.number)
if err != nil {
return err
}
err = m.AttachCSVFilePools(ctx, exec, rel2...)
err = m.AttachCSVFilePools(ctx, exec, rel3...)
if err != nil {
return err
}
@ -602,6 +640,54 @@ func (m fileuploadCSVMods) WithoutCSVFileErrorCSVS() FileuploadCSVMod {
})
}
func (m fileuploadCSVMods) WithCSVFileFlyoverAerialServices(number int, related *FileuploadFlyoverAerialServiceTemplate) FileuploadCSVMod {
return FileuploadCSVModFunc(func(ctx context.Context, o *FileuploadCSVTemplate) {
o.r.CSVFileFlyoverAerialServices = []*fileuploadCSVRCSVFileFlyoverAerialServicesR{{
number: number,
o: related,
}}
})
}
func (m fileuploadCSVMods) WithNewCSVFileFlyoverAerialServices(number int, mods ...FileuploadFlyoverAerialServiceMod) FileuploadCSVMod {
return FileuploadCSVModFunc(func(ctx context.Context, o *FileuploadCSVTemplate) {
related := o.f.NewFileuploadFlyoverAerialServiceWithContext(ctx, mods...)
m.WithCSVFileFlyoverAerialServices(number, related).Apply(ctx, o)
})
}
func (m fileuploadCSVMods) AddCSVFileFlyoverAerialServices(number int, related *FileuploadFlyoverAerialServiceTemplate) FileuploadCSVMod {
return FileuploadCSVModFunc(func(ctx context.Context, o *FileuploadCSVTemplate) {
o.r.CSVFileFlyoverAerialServices = append(o.r.CSVFileFlyoverAerialServices, &fileuploadCSVRCSVFileFlyoverAerialServicesR{
number: number,
o: related,
})
})
}
func (m fileuploadCSVMods) AddNewCSVFileFlyoverAerialServices(number int, mods ...FileuploadFlyoverAerialServiceMod) FileuploadCSVMod {
return FileuploadCSVModFunc(func(ctx context.Context, o *FileuploadCSVTemplate) {
related := o.f.NewFileuploadFlyoverAerialServiceWithContext(ctx, mods...)
m.AddCSVFileFlyoverAerialServices(number, related).Apply(ctx, o)
})
}
func (m fileuploadCSVMods) AddExistingCSVFileFlyoverAerialServices(existingModels ...*models.FileuploadFlyoverAerialService) FileuploadCSVMod {
return FileuploadCSVModFunc(func(ctx context.Context, o *FileuploadCSVTemplate) {
for _, em := range existingModels {
o.r.CSVFileFlyoverAerialServices = append(o.r.CSVFileFlyoverAerialServices, &fileuploadCSVRCSVFileFlyoverAerialServicesR{
o: o.f.FromExistingFileuploadFlyoverAerialService(em),
})
}
})
}
func (m fileuploadCSVMods) WithoutCSVFileFlyoverAerialServices() FileuploadCSVMod {
return FileuploadCSVModFunc(func(ctx context.Context, o *FileuploadCSVTemplate) {
o.r.CSVFileFlyoverAerialServices = nil
})
}
func (m fileuploadCSVMods) WithCSVFilePools(number int, related *FileuploadPoolTemplate) FileuploadCSVMod {
return FileuploadCSVModFunc(func(ctx context.Context, o *FileuploadCSVTemplate) {
o.r.CSVFilePools = []*fileuploadCSVRCSVFilePoolsR{{

View file

@ -0,0 +1,903 @@
// Code generated by BobGen psql v0.42.5. DO NOT EDIT.
// This file is meant to be re-generated in place and/or deleted at any time.
package factory
import (
"context"
"testing"
"time"
"github.com/Gleipnir-Technology/bob"
enums "github.com/Gleipnir-Technology/nidus-sync/db/enums"
models "github.com/Gleipnir-Technology/nidus-sync/db/models"
"github.com/aarondl/opt/null"
"github.com/aarondl/opt/omit"
"github.com/aarondl/opt/omitnull"
"github.com/jaswdr/faker/v2"
)
type FileuploadFlyoverAerialServiceMod interface {
Apply(context.Context, *FileuploadFlyoverAerialServiceTemplate)
}
type FileuploadFlyoverAerialServiceModFunc func(context.Context, *FileuploadFlyoverAerialServiceTemplate)
func (f FileuploadFlyoverAerialServiceModFunc) Apply(ctx context.Context, n *FileuploadFlyoverAerialServiceTemplate) {
f(ctx, n)
}
type FileuploadFlyoverAerialServiceModSlice []FileuploadFlyoverAerialServiceMod
func (mods FileuploadFlyoverAerialServiceModSlice) Apply(ctx context.Context, n *FileuploadFlyoverAerialServiceTemplate) {
for _, f := range mods {
f.Apply(ctx, n)
}
}
// FileuploadFlyoverAerialServiceTemplate is an object representing the database table.
// all columns are optional and should be set by mods
type FileuploadFlyoverAerialServiceTemplate struct {
Committed func() bool
Condition func() enums.FileuploadPoolconditiontype
Created func() time.Time
CreatorID func() int32
CSVFile func() int32
Deleted func() null.Val[time.Time]
Geom func() null.Val[string]
H3cell func() null.Val[string]
ID func() int32
OrganizationID func() int32
r fileuploadFlyoverAerialServiceR
f *Factory
alreadyPersisted bool
}
type fileuploadFlyoverAerialServiceR struct {
CreatorUser *fileuploadFlyoverAerialServiceRCreatorUserR
CSVFileCSV *fileuploadFlyoverAerialServiceRCSVFileCSVR
Organization *fileuploadFlyoverAerialServiceROrganizationR
}
type fileuploadFlyoverAerialServiceRCreatorUserR struct {
o *UserTemplate
}
type fileuploadFlyoverAerialServiceRCSVFileCSVR struct {
o *FileuploadCSVTemplate
}
type fileuploadFlyoverAerialServiceROrganizationR struct {
o *OrganizationTemplate
}
// Apply mods to the FileuploadFlyoverAerialServiceTemplate
func (o *FileuploadFlyoverAerialServiceTemplate) Apply(ctx context.Context, mods ...FileuploadFlyoverAerialServiceMod) {
for _, mod := range mods {
mod.Apply(ctx, o)
}
}
// setModelRels creates and sets the relationships on *models.FileuploadFlyoverAerialService
// according to the relationships in the template. Nothing is inserted into the db
func (t FileuploadFlyoverAerialServiceTemplate) setModelRels(o *models.FileuploadFlyoverAerialService) {
if t.r.CreatorUser != nil {
rel := t.r.CreatorUser.o.Build()
rel.R.CreatorFlyoverAerialServices = append(rel.R.CreatorFlyoverAerialServices, o)
o.CreatorID = rel.ID // h2
o.R.CreatorUser = rel
}
if t.r.CSVFileCSV != nil {
rel := t.r.CSVFileCSV.o.Build()
rel.R.CSVFileFlyoverAerialServices = append(rel.R.CSVFileFlyoverAerialServices, o)
o.CSVFile = rel.FileID // h2
o.R.CSVFileCSV = rel
}
if t.r.Organization != nil {
rel := t.r.Organization.o.Build()
rel.R.FlyoverAerialServices = append(rel.R.FlyoverAerialServices, o)
o.OrganizationID = rel.ID // h2
o.R.Organization = rel
}
}
// BuildSetter returns an *models.FileuploadFlyoverAerialServiceSetter
// this does nothing with the relationship templates
func (o FileuploadFlyoverAerialServiceTemplate) BuildSetter() *models.FileuploadFlyoverAerialServiceSetter {
m := &models.FileuploadFlyoverAerialServiceSetter{}
if o.Committed != nil {
val := o.Committed()
m.Committed = omit.From(val)
}
if o.Condition != nil {
val := o.Condition()
m.Condition = omit.From(val)
}
if o.Created != nil {
val := o.Created()
m.Created = omit.From(val)
}
if o.CreatorID != nil {
val := o.CreatorID()
m.CreatorID = omit.From(val)
}
if o.CSVFile != nil {
val := o.CSVFile()
m.CSVFile = omit.From(val)
}
if o.Deleted != nil {
val := o.Deleted()
m.Deleted = omitnull.FromNull(val)
}
if o.Geom != nil {
val := o.Geom()
m.Geom = omitnull.FromNull(val)
}
if o.H3cell != nil {
val := o.H3cell()
m.H3cell = omitnull.FromNull(val)
}
if o.ID != nil {
val := o.ID()
m.ID = omit.From(val)
}
if o.OrganizationID != nil {
val := o.OrganizationID()
m.OrganizationID = omit.From(val)
}
return m
}
// BuildManySetter returns an []*models.FileuploadFlyoverAerialServiceSetter
// this does nothing with the relationship templates
func (o FileuploadFlyoverAerialServiceTemplate) BuildManySetter(number int) []*models.FileuploadFlyoverAerialServiceSetter {
m := make([]*models.FileuploadFlyoverAerialServiceSetter, number)
for i := range m {
m[i] = o.BuildSetter()
}
return m
}
// Build returns an *models.FileuploadFlyoverAerialService
// Related objects are also created and placed in the .R field
// NOTE: Objects are not inserted into the database. Use FileuploadFlyoverAerialServiceTemplate.Create
func (o FileuploadFlyoverAerialServiceTemplate) Build() *models.FileuploadFlyoverAerialService {
m := &models.FileuploadFlyoverAerialService{}
if o.Committed != nil {
m.Committed = o.Committed()
}
if o.Condition != nil {
m.Condition = o.Condition()
}
if o.Created != nil {
m.Created = o.Created()
}
if o.CreatorID != nil {
m.CreatorID = o.CreatorID()
}
if o.CSVFile != nil {
m.CSVFile = o.CSVFile()
}
if o.Deleted != nil {
m.Deleted = o.Deleted()
}
if o.Geom != nil {
m.Geom = o.Geom()
}
if o.H3cell != nil {
m.H3cell = o.H3cell()
}
if o.ID != nil {
m.ID = o.ID()
}
if o.OrganizationID != nil {
m.OrganizationID = o.OrganizationID()
}
o.setModelRels(m)
return m
}
// BuildMany returns an models.FileuploadFlyoverAerialServiceSlice
// Related objects are also created and placed in the .R field
// NOTE: Objects are not inserted into the database. Use FileuploadFlyoverAerialServiceTemplate.CreateMany
func (o FileuploadFlyoverAerialServiceTemplate) BuildMany(number int) models.FileuploadFlyoverAerialServiceSlice {
m := make(models.FileuploadFlyoverAerialServiceSlice, number)
for i := range m {
m[i] = o.Build()
}
return m
}
func ensureCreatableFileuploadFlyoverAerialService(m *models.FileuploadFlyoverAerialServiceSetter) {
if !(m.Committed.IsValue()) {
val := random_bool(nil)
m.Committed = omit.From(val)
}
if !(m.Condition.IsValue()) {
val := random_enums_FileuploadPoolconditiontype(nil)
m.Condition = omit.From(val)
}
if !(m.Created.IsValue()) {
val := random_time_Time(nil)
m.Created = omit.From(val)
}
if !(m.CreatorID.IsValue()) {
val := random_int32(nil)
m.CreatorID = omit.From(val)
}
if !(m.CSVFile.IsValue()) {
val := random_int32(nil)
m.CSVFile = omit.From(val)
}
if !(m.OrganizationID.IsValue()) {
val := random_int32(nil)
m.OrganizationID = omit.From(val)
}
}
// insertOptRels creates and inserts any optional the relationships on *models.FileuploadFlyoverAerialService
// according to the relationships in the template.
// any required relationship should have already exist on the model
func (o *FileuploadFlyoverAerialServiceTemplate) insertOptRels(ctx context.Context, exec bob.Executor, m *models.FileuploadFlyoverAerialService) error {
var err error
return err
}
// Create builds a fileuploadFlyoverAerialService and inserts it into the database
// Relations objects are also inserted and placed in the .R field
func (o *FileuploadFlyoverAerialServiceTemplate) Create(ctx context.Context, exec bob.Executor) (*models.FileuploadFlyoverAerialService, error) {
var err error
opt := o.BuildSetter()
ensureCreatableFileuploadFlyoverAerialService(opt)
if o.r.CreatorUser == nil {
FileuploadFlyoverAerialServiceMods.WithNewCreatorUser().Apply(ctx, o)
}
var rel0 *models.User
if o.r.CreatorUser.o.alreadyPersisted {
rel0 = o.r.CreatorUser.o.Build()
} else {
rel0, err = o.r.CreatorUser.o.Create(ctx, exec)
if err != nil {
return nil, err
}
}
opt.CreatorID = omit.From(rel0.ID)
if o.r.CSVFileCSV == nil {
FileuploadFlyoverAerialServiceMods.WithNewCSVFileCSV().Apply(ctx, o)
}
var rel1 *models.FileuploadCSV
if o.r.CSVFileCSV.o.alreadyPersisted {
rel1 = o.r.CSVFileCSV.o.Build()
} else {
rel1, err = o.r.CSVFileCSV.o.Create(ctx, exec)
if err != nil {
return nil, err
}
}
opt.CSVFile = omit.From(rel1.FileID)
if o.r.Organization == nil {
FileuploadFlyoverAerialServiceMods.WithNewOrganization().Apply(ctx, o)
}
var rel2 *models.Organization
if o.r.Organization.o.alreadyPersisted {
rel2 = o.r.Organization.o.Build()
} else {
rel2, err = o.r.Organization.o.Create(ctx, exec)
if err != nil {
return nil, err
}
}
opt.OrganizationID = omit.From(rel2.ID)
m, err := models.FileuploadFlyoverAerialServices.Insert(opt).One(ctx, exec)
if err != nil {
return nil, err
}
m.R.CreatorUser = rel0
m.R.CSVFileCSV = rel1
m.R.Organization = rel2
if err := o.insertOptRels(ctx, exec, m); err != nil {
return nil, err
}
return m, err
}
// MustCreate builds a fileuploadFlyoverAerialService and inserts it into the database
// Relations objects are also inserted and placed in the .R field
// panics if an error occurs
func (o *FileuploadFlyoverAerialServiceTemplate) MustCreate(ctx context.Context, exec bob.Executor) *models.FileuploadFlyoverAerialService {
m, err := o.Create(ctx, exec)
if err != nil {
panic(err)
}
return m
}
// CreateOrFail builds a fileuploadFlyoverAerialService 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 *FileuploadFlyoverAerialServiceTemplate) CreateOrFail(ctx context.Context, tb testing.TB, exec bob.Executor) *models.FileuploadFlyoverAerialService {
tb.Helper()
m, err := o.Create(ctx, exec)
if err != nil {
tb.Fatal(err)
return nil
}
return m
}
// CreateMany builds multiple fileuploadFlyoverAerialServices and inserts them into the database
// Relations objects are also inserted and placed in the .R field
func (o FileuploadFlyoverAerialServiceTemplate) CreateMany(ctx context.Context, exec bob.Executor, number int) (models.FileuploadFlyoverAerialServiceSlice, error) {
var err error
m := make(models.FileuploadFlyoverAerialServiceSlice, number)
for i := range m {
m[i], err = o.Create(ctx, exec)
if err != nil {
return nil, err
}
}
return m, nil
}
// MustCreateMany builds multiple fileuploadFlyoverAerialServices and inserts them into the database
// Relations objects are also inserted and placed in the .R field
// panics if an error occurs
func (o FileuploadFlyoverAerialServiceTemplate) MustCreateMany(ctx context.Context, exec bob.Executor, number int) models.FileuploadFlyoverAerialServiceSlice {
m, err := o.CreateMany(ctx, exec, number)
if err != nil {
panic(err)
}
return m
}
// CreateManyOrFail builds multiple fileuploadFlyoverAerialServices 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 FileuploadFlyoverAerialServiceTemplate) CreateManyOrFail(ctx context.Context, tb testing.TB, exec bob.Executor, number int) models.FileuploadFlyoverAerialServiceSlice {
tb.Helper()
m, err := o.CreateMany(ctx, exec, number)
if err != nil {
tb.Fatal(err)
return nil
}
return m
}
// FileuploadFlyoverAerialService has methods that act as mods for the FileuploadFlyoverAerialServiceTemplate
var FileuploadFlyoverAerialServiceMods fileuploadFlyoverAerialServiceMods
type fileuploadFlyoverAerialServiceMods struct{}
func (m fileuploadFlyoverAerialServiceMods) RandomizeAllColumns(f *faker.Faker) FileuploadFlyoverAerialServiceMod {
return FileuploadFlyoverAerialServiceModSlice{
FileuploadFlyoverAerialServiceMods.RandomCommitted(f),
FileuploadFlyoverAerialServiceMods.RandomCondition(f),
FileuploadFlyoverAerialServiceMods.RandomCreated(f),
FileuploadFlyoverAerialServiceMods.RandomCreatorID(f),
FileuploadFlyoverAerialServiceMods.RandomCSVFile(f),
FileuploadFlyoverAerialServiceMods.RandomDeleted(f),
FileuploadFlyoverAerialServiceMods.RandomGeom(f),
FileuploadFlyoverAerialServiceMods.RandomH3cell(f),
FileuploadFlyoverAerialServiceMods.RandomID(f),
FileuploadFlyoverAerialServiceMods.RandomOrganizationID(f),
}
}
// Set the model columns to this value
func (m fileuploadFlyoverAerialServiceMods) Committed(val bool) FileuploadFlyoverAerialServiceMod {
return FileuploadFlyoverAerialServiceModFunc(func(_ context.Context, o *FileuploadFlyoverAerialServiceTemplate) {
o.Committed = func() bool { return val }
})
}
// Set the Column from the function
func (m fileuploadFlyoverAerialServiceMods) CommittedFunc(f func() bool) FileuploadFlyoverAerialServiceMod {
return FileuploadFlyoverAerialServiceModFunc(func(_ context.Context, o *FileuploadFlyoverAerialServiceTemplate) {
o.Committed = f
})
}
// Clear any values for the column
func (m fileuploadFlyoverAerialServiceMods) UnsetCommitted() FileuploadFlyoverAerialServiceMod {
return FileuploadFlyoverAerialServiceModFunc(func(_ context.Context, o *FileuploadFlyoverAerialServiceTemplate) {
o.Committed = nil
})
}
// Generates a random value for the column using the given faker
// if faker is nil, a default faker is used
func (m fileuploadFlyoverAerialServiceMods) RandomCommitted(f *faker.Faker) FileuploadFlyoverAerialServiceMod {
return FileuploadFlyoverAerialServiceModFunc(func(_ context.Context, o *FileuploadFlyoverAerialServiceTemplate) {
o.Committed = func() bool {
return random_bool(f)
}
})
}
// Set the model columns to this value
func (m fileuploadFlyoverAerialServiceMods) Condition(val enums.FileuploadPoolconditiontype) FileuploadFlyoverAerialServiceMod {
return FileuploadFlyoverAerialServiceModFunc(func(_ context.Context, o *FileuploadFlyoverAerialServiceTemplate) {
o.Condition = func() enums.FileuploadPoolconditiontype { return val }
})
}
// Set the Column from the function
func (m fileuploadFlyoverAerialServiceMods) ConditionFunc(f func() enums.FileuploadPoolconditiontype) FileuploadFlyoverAerialServiceMod {
return FileuploadFlyoverAerialServiceModFunc(func(_ context.Context, o *FileuploadFlyoverAerialServiceTemplate) {
o.Condition = f
})
}
// Clear any values for the column
func (m fileuploadFlyoverAerialServiceMods) UnsetCondition() FileuploadFlyoverAerialServiceMod {
return FileuploadFlyoverAerialServiceModFunc(func(_ context.Context, o *FileuploadFlyoverAerialServiceTemplate) {
o.Condition = nil
})
}
// Generates a random value for the column using the given faker
// if faker is nil, a default faker is used
func (m fileuploadFlyoverAerialServiceMods) RandomCondition(f *faker.Faker) FileuploadFlyoverAerialServiceMod {
return FileuploadFlyoverAerialServiceModFunc(func(_ context.Context, o *FileuploadFlyoverAerialServiceTemplate) {
o.Condition = func() enums.FileuploadPoolconditiontype {
return random_enums_FileuploadPoolconditiontype(f)
}
})
}
// Set the model columns to this value
func (m fileuploadFlyoverAerialServiceMods) Created(val time.Time) FileuploadFlyoverAerialServiceMod {
return FileuploadFlyoverAerialServiceModFunc(func(_ context.Context, o *FileuploadFlyoverAerialServiceTemplate) {
o.Created = func() time.Time { return val }
})
}
// Set the Column from the function
func (m fileuploadFlyoverAerialServiceMods) CreatedFunc(f func() time.Time) FileuploadFlyoverAerialServiceMod {
return FileuploadFlyoverAerialServiceModFunc(func(_ context.Context, o *FileuploadFlyoverAerialServiceTemplate) {
o.Created = f
})
}
// Clear any values for the column
func (m fileuploadFlyoverAerialServiceMods) UnsetCreated() FileuploadFlyoverAerialServiceMod {
return FileuploadFlyoverAerialServiceModFunc(func(_ context.Context, o *FileuploadFlyoverAerialServiceTemplate) {
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 fileuploadFlyoverAerialServiceMods) RandomCreated(f *faker.Faker) FileuploadFlyoverAerialServiceMod {
return FileuploadFlyoverAerialServiceModFunc(func(_ context.Context, o *FileuploadFlyoverAerialServiceTemplate) {
o.Created = func() time.Time {
return random_time_Time(f)
}
})
}
// Set the model columns to this value
func (m fileuploadFlyoverAerialServiceMods) CreatorID(val int32) FileuploadFlyoverAerialServiceMod {
return FileuploadFlyoverAerialServiceModFunc(func(_ context.Context, o *FileuploadFlyoverAerialServiceTemplate) {
o.CreatorID = func() int32 { return val }
})
}
// Set the Column from the function
func (m fileuploadFlyoverAerialServiceMods) CreatorIDFunc(f func() int32) FileuploadFlyoverAerialServiceMod {
return FileuploadFlyoverAerialServiceModFunc(func(_ context.Context, o *FileuploadFlyoverAerialServiceTemplate) {
o.CreatorID = f
})
}
// Clear any values for the column
func (m fileuploadFlyoverAerialServiceMods) UnsetCreatorID() FileuploadFlyoverAerialServiceMod {
return FileuploadFlyoverAerialServiceModFunc(func(_ context.Context, o *FileuploadFlyoverAerialServiceTemplate) {
o.CreatorID = nil
})
}
// Generates a random value for the column using the given faker
// if faker is nil, a default faker is used
func (m fileuploadFlyoverAerialServiceMods) RandomCreatorID(f *faker.Faker) FileuploadFlyoverAerialServiceMod {
return FileuploadFlyoverAerialServiceModFunc(func(_ context.Context, o *FileuploadFlyoverAerialServiceTemplate) {
o.CreatorID = func() int32 {
return random_int32(f)
}
})
}
// Set the model columns to this value
func (m fileuploadFlyoverAerialServiceMods) CSVFile(val int32) FileuploadFlyoverAerialServiceMod {
return FileuploadFlyoverAerialServiceModFunc(func(_ context.Context, o *FileuploadFlyoverAerialServiceTemplate) {
o.CSVFile = func() int32 { return val }
})
}
// Set the Column from the function
func (m fileuploadFlyoverAerialServiceMods) CSVFileFunc(f func() int32) FileuploadFlyoverAerialServiceMod {
return FileuploadFlyoverAerialServiceModFunc(func(_ context.Context, o *FileuploadFlyoverAerialServiceTemplate) {
o.CSVFile = f
})
}
// Clear any values for the column
func (m fileuploadFlyoverAerialServiceMods) UnsetCSVFile() FileuploadFlyoverAerialServiceMod {
return FileuploadFlyoverAerialServiceModFunc(func(_ context.Context, o *FileuploadFlyoverAerialServiceTemplate) {
o.CSVFile = nil
})
}
// Generates a random value for the column using the given faker
// if faker is nil, a default faker is used
func (m fileuploadFlyoverAerialServiceMods) RandomCSVFile(f *faker.Faker) FileuploadFlyoverAerialServiceMod {
return FileuploadFlyoverAerialServiceModFunc(func(_ context.Context, o *FileuploadFlyoverAerialServiceTemplate) {
o.CSVFile = func() int32 {
return random_int32(f)
}
})
}
// Set the model columns to this value
func (m fileuploadFlyoverAerialServiceMods) Deleted(val null.Val[time.Time]) FileuploadFlyoverAerialServiceMod {
return FileuploadFlyoverAerialServiceModFunc(func(_ context.Context, o *FileuploadFlyoverAerialServiceTemplate) {
o.Deleted = func() null.Val[time.Time] { return val }
})
}
// Set the Column from the function
func (m fileuploadFlyoverAerialServiceMods) DeletedFunc(f func() null.Val[time.Time]) FileuploadFlyoverAerialServiceMod {
return FileuploadFlyoverAerialServiceModFunc(func(_ context.Context, o *FileuploadFlyoverAerialServiceTemplate) {
o.Deleted = f
})
}
// Clear any values for the column
func (m fileuploadFlyoverAerialServiceMods) UnsetDeleted() FileuploadFlyoverAerialServiceMod {
return FileuploadFlyoverAerialServiceModFunc(func(_ context.Context, o *FileuploadFlyoverAerialServiceTemplate) {
o.Deleted = 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 fileuploadFlyoverAerialServiceMods) RandomDeleted(f *faker.Faker) FileuploadFlyoverAerialServiceMod {
return FileuploadFlyoverAerialServiceModFunc(func(_ context.Context, o *FileuploadFlyoverAerialServiceTemplate) {
o.Deleted = func() null.Val[time.Time] {
if f == nil {
f = &defaultFaker
}
val := random_time_Time(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 fileuploadFlyoverAerialServiceMods) RandomDeletedNotNull(f *faker.Faker) FileuploadFlyoverAerialServiceMod {
return FileuploadFlyoverAerialServiceModFunc(func(_ context.Context, o *FileuploadFlyoverAerialServiceTemplate) {
o.Deleted = func() null.Val[time.Time] {
if f == nil {
f = &defaultFaker
}
val := random_time_Time(f)
return null.From(val)
}
})
}
// Set the model columns to this value
func (m fileuploadFlyoverAerialServiceMods) Geom(val null.Val[string]) FileuploadFlyoverAerialServiceMod {
return FileuploadFlyoverAerialServiceModFunc(func(_ context.Context, o *FileuploadFlyoverAerialServiceTemplate) {
o.Geom = func() null.Val[string] { return val }
})
}
// Set the Column from the function
func (m fileuploadFlyoverAerialServiceMods) GeomFunc(f func() null.Val[string]) FileuploadFlyoverAerialServiceMod {
return FileuploadFlyoverAerialServiceModFunc(func(_ context.Context, o *FileuploadFlyoverAerialServiceTemplate) {
o.Geom = f
})
}
// Clear any values for the column
func (m fileuploadFlyoverAerialServiceMods) UnsetGeom() FileuploadFlyoverAerialServiceMod {
return FileuploadFlyoverAerialServiceModFunc(func(_ context.Context, o *FileuploadFlyoverAerialServiceTemplate) {
o.Geom = 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 fileuploadFlyoverAerialServiceMods) RandomGeom(f *faker.Faker) FileuploadFlyoverAerialServiceMod {
return FileuploadFlyoverAerialServiceModFunc(func(_ context.Context, o *FileuploadFlyoverAerialServiceTemplate) {
o.Geom = 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 fileuploadFlyoverAerialServiceMods) RandomGeomNotNull(f *faker.Faker) FileuploadFlyoverAerialServiceMod {
return FileuploadFlyoverAerialServiceModFunc(func(_ context.Context, o *FileuploadFlyoverAerialServiceTemplate) {
o.Geom = 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 fileuploadFlyoverAerialServiceMods) H3cell(val null.Val[string]) FileuploadFlyoverAerialServiceMod {
return FileuploadFlyoverAerialServiceModFunc(func(_ context.Context, o *FileuploadFlyoverAerialServiceTemplate) {
o.H3cell = func() null.Val[string] { return val }
})
}
// Set the Column from the function
func (m fileuploadFlyoverAerialServiceMods) H3cellFunc(f func() null.Val[string]) FileuploadFlyoverAerialServiceMod {
return FileuploadFlyoverAerialServiceModFunc(func(_ context.Context, o *FileuploadFlyoverAerialServiceTemplate) {
o.H3cell = f
})
}
// Clear any values for the column
func (m fileuploadFlyoverAerialServiceMods) UnsetH3cell() FileuploadFlyoverAerialServiceMod {
return FileuploadFlyoverAerialServiceModFunc(func(_ context.Context, o *FileuploadFlyoverAerialServiceTemplate) {
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 fileuploadFlyoverAerialServiceMods) RandomH3cell(f *faker.Faker) FileuploadFlyoverAerialServiceMod {
return FileuploadFlyoverAerialServiceModFunc(func(_ context.Context, o *FileuploadFlyoverAerialServiceTemplate) {
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 fileuploadFlyoverAerialServiceMods) RandomH3cellNotNull(f *faker.Faker) FileuploadFlyoverAerialServiceMod {
return FileuploadFlyoverAerialServiceModFunc(func(_ context.Context, o *FileuploadFlyoverAerialServiceTemplate) {
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 fileuploadFlyoverAerialServiceMods) ID(val int32) FileuploadFlyoverAerialServiceMod {
return FileuploadFlyoverAerialServiceModFunc(func(_ context.Context, o *FileuploadFlyoverAerialServiceTemplate) {
o.ID = func() int32 { return val }
})
}
// Set the Column from the function
func (m fileuploadFlyoverAerialServiceMods) IDFunc(f func() int32) FileuploadFlyoverAerialServiceMod {
return FileuploadFlyoverAerialServiceModFunc(func(_ context.Context, o *FileuploadFlyoverAerialServiceTemplate) {
o.ID = f
})
}
// Clear any values for the column
func (m fileuploadFlyoverAerialServiceMods) UnsetID() FileuploadFlyoverAerialServiceMod {
return FileuploadFlyoverAerialServiceModFunc(func(_ context.Context, o *FileuploadFlyoverAerialServiceTemplate) {
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 fileuploadFlyoverAerialServiceMods) RandomID(f *faker.Faker) FileuploadFlyoverAerialServiceMod {
return FileuploadFlyoverAerialServiceModFunc(func(_ context.Context, o *FileuploadFlyoverAerialServiceTemplate) {
o.ID = func() int32 {
return random_int32(f)
}
})
}
// Set the model columns to this value
func (m fileuploadFlyoverAerialServiceMods) OrganizationID(val int32) FileuploadFlyoverAerialServiceMod {
return FileuploadFlyoverAerialServiceModFunc(func(_ context.Context, o *FileuploadFlyoverAerialServiceTemplate) {
o.OrganizationID = func() int32 { return val }
})
}
// Set the Column from the function
func (m fileuploadFlyoverAerialServiceMods) OrganizationIDFunc(f func() int32) FileuploadFlyoverAerialServiceMod {
return FileuploadFlyoverAerialServiceModFunc(func(_ context.Context, o *FileuploadFlyoverAerialServiceTemplate) {
o.OrganizationID = f
})
}
// Clear any values for the column
func (m fileuploadFlyoverAerialServiceMods) UnsetOrganizationID() FileuploadFlyoverAerialServiceMod {
return FileuploadFlyoverAerialServiceModFunc(func(_ context.Context, o *FileuploadFlyoverAerialServiceTemplate) {
o.OrganizationID = nil
})
}
// Generates a random value for the column using the given faker
// if faker is nil, a default faker is used
func (m fileuploadFlyoverAerialServiceMods) RandomOrganizationID(f *faker.Faker) FileuploadFlyoverAerialServiceMod {
return FileuploadFlyoverAerialServiceModFunc(func(_ context.Context, o *FileuploadFlyoverAerialServiceTemplate) {
o.OrganizationID = func() int32 {
return random_int32(f)
}
})
}
func (m fileuploadFlyoverAerialServiceMods) WithParentsCascading() FileuploadFlyoverAerialServiceMod {
return FileuploadFlyoverAerialServiceModFunc(func(ctx context.Context, o *FileuploadFlyoverAerialServiceTemplate) {
if isDone, _ := fileuploadFlyoverAerialServiceWithParentsCascadingCtx.Value(ctx); isDone {
return
}
ctx = fileuploadFlyoverAerialServiceWithParentsCascadingCtx.WithValue(ctx, true)
{
related := o.f.NewUserWithContext(ctx, UserMods.WithParentsCascading())
m.WithCreatorUser(related).Apply(ctx, o)
}
{
related := o.f.NewFileuploadCSVWithContext(ctx, FileuploadCSVMods.WithParentsCascading())
m.WithCSVFileCSV(related).Apply(ctx, o)
}
{
related := o.f.NewOrganizationWithContext(ctx, OrganizationMods.WithParentsCascading())
m.WithOrganization(related).Apply(ctx, o)
}
})
}
func (m fileuploadFlyoverAerialServiceMods) WithCreatorUser(rel *UserTemplate) FileuploadFlyoverAerialServiceMod {
return FileuploadFlyoverAerialServiceModFunc(func(ctx context.Context, o *FileuploadFlyoverAerialServiceTemplate) {
o.r.CreatorUser = &fileuploadFlyoverAerialServiceRCreatorUserR{
o: rel,
}
})
}
func (m fileuploadFlyoverAerialServiceMods) WithNewCreatorUser(mods ...UserMod) FileuploadFlyoverAerialServiceMod {
return FileuploadFlyoverAerialServiceModFunc(func(ctx context.Context, o *FileuploadFlyoverAerialServiceTemplate) {
related := o.f.NewUserWithContext(ctx, mods...)
m.WithCreatorUser(related).Apply(ctx, o)
})
}
func (m fileuploadFlyoverAerialServiceMods) WithExistingCreatorUser(em *models.User) FileuploadFlyoverAerialServiceMod {
return FileuploadFlyoverAerialServiceModFunc(func(ctx context.Context, o *FileuploadFlyoverAerialServiceTemplate) {
o.r.CreatorUser = &fileuploadFlyoverAerialServiceRCreatorUserR{
o: o.f.FromExistingUser(em),
}
})
}
func (m fileuploadFlyoverAerialServiceMods) WithoutCreatorUser() FileuploadFlyoverAerialServiceMod {
return FileuploadFlyoverAerialServiceModFunc(func(ctx context.Context, o *FileuploadFlyoverAerialServiceTemplate) {
o.r.CreatorUser = nil
})
}
func (m fileuploadFlyoverAerialServiceMods) WithCSVFileCSV(rel *FileuploadCSVTemplate) FileuploadFlyoverAerialServiceMod {
return FileuploadFlyoverAerialServiceModFunc(func(ctx context.Context, o *FileuploadFlyoverAerialServiceTemplate) {
o.r.CSVFileCSV = &fileuploadFlyoverAerialServiceRCSVFileCSVR{
o: rel,
}
})
}
func (m fileuploadFlyoverAerialServiceMods) WithNewCSVFileCSV(mods ...FileuploadCSVMod) FileuploadFlyoverAerialServiceMod {
return FileuploadFlyoverAerialServiceModFunc(func(ctx context.Context, o *FileuploadFlyoverAerialServiceTemplate) {
related := o.f.NewFileuploadCSVWithContext(ctx, mods...)
m.WithCSVFileCSV(related).Apply(ctx, o)
})
}
func (m fileuploadFlyoverAerialServiceMods) WithExistingCSVFileCSV(em *models.FileuploadCSV) FileuploadFlyoverAerialServiceMod {
return FileuploadFlyoverAerialServiceModFunc(func(ctx context.Context, o *FileuploadFlyoverAerialServiceTemplate) {
o.r.CSVFileCSV = &fileuploadFlyoverAerialServiceRCSVFileCSVR{
o: o.f.FromExistingFileuploadCSV(em),
}
})
}
func (m fileuploadFlyoverAerialServiceMods) WithoutCSVFileCSV() FileuploadFlyoverAerialServiceMod {
return FileuploadFlyoverAerialServiceModFunc(func(ctx context.Context, o *FileuploadFlyoverAerialServiceTemplate) {
o.r.CSVFileCSV = nil
})
}
func (m fileuploadFlyoverAerialServiceMods) WithOrganization(rel *OrganizationTemplate) FileuploadFlyoverAerialServiceMod {
return FileuploadFlyoverAerialServiceModFunc(func(ctx context.Context, o *FileuploadFlyoverAerialServiceTemplate) {
o.r.Organization = &fileuploadFlyoverAerialServiceROrganizationR{
o: rel,
}
})
}
func (m fileuploadFlyoverAerialServiceMods) WithNewOrganization(mods ...OrganizationMod) FileuploadFlyoverAerialServiceMod {
return FileuploadFlyoverAerialServiceModFunc(func(ctx context.Context, o *FileuploadFlyoverAerialServiceTemplate) {
related := o.f.NewOrganizationWithContext(ctx, mods...)
m.WithOrganization(related).Apply(ctx, o)
})
}
func (m fileuploadFlyoverAerialServiceMods) WithExistingOrganization(em *models.Organization) FileuploadFlyoverAerialServiceMod {
return FileuploadFlyoverAerialServiceModFunc(func(ctx context.Context, o *FileuploadFlyoverAerialServiceTemplate) {
o.r.Organization = &fileuploadFlyoverAerialServiceROrganizationR{
o: o.f.FromExistingOrganization(em),
}
})
}
func (m fileuploadFlyoverAerialServiceMods) WithoutOrganization() FileuploadFlyoverAerialServiceMod {
return FileuploadFlyoverAerialServiceModFunc(func(ctx context.Context, o *FileuploadFlyoverAerialServiceTemplate) {
o.r.Organization = nil
})
}

View file

@ -112,6 +112,7 @@ type organizationR struct {
Zones2s []*organizationRZones2sR
FieldseekerSyncs []*organizationRFieldseekerSyncsR
Files []*organizationRFilesR
FlyoverAerialServices []*organizationRFlyoverAerialServicesR
Pools []*organizationRPoolsR
H3Aggregations []*organizationRH3AggregationsR
NoteAudios []*organizationRNoteAudiosR
@ -260,6 +261,10 @@ type organizationRFilesR struct {
number int
o *FileuploadFileTemplate
}
type organizationRFlyoverAerialServicesR struct {
number int
o *FileuploadFlyoverAerialServiceTemplate
}
type organizationRPoolsR struct {
number int
o *FileuploadPoolTemplate
@ -749,6 +754,19 @@ func (t OrganizationTemplate) setModelRels(o *models.Organization) {
o.R.Files = rel
}
if t.r.FlyoverAerialServices != nil {
rel := models.FileuploadFlyoverAerialServiceSlice{}
for _, r := range t.r.FlyoverAerialServices {
related := r.o.BuildMany(r.number)
for _, rel := range related {
rel.OrganizationID = o.ID // h2
rel.R.Organization = o
}
rel = append(rel, related...)
}
o.R.FlyoverAerialServices = rel
}
if t.r.Pools != nil {
rel := models.FileuploadPoolSlice{}
for _, r := range t.r.Pools {
@ -1791,6 +1809,26 @@ func (o *OrganizationTemplate) insertOptRels(ctx context.Context, exec bob.Execu
}
}
isFlyoverAerialServicesDone, _ := organizationRelFlyoverAerialServicesCtx.Value(ctx)
if !isFlyoverAerialServicesDone && o.r.FlyoverAerialServices != nil {
ctx = organizationRelFlyoverAerialServicesCtx.WithValue(ctx, true)
for _, r := range o.r.FlyoverAerialServices {
if r.o.alreadyPersisted {
m.R.FlyoverAerialServices = append(m.R.FlyoverAerialServices, r.o.Build())
} else {
rel34, err := r.o.CreateMany(ctx, exec, r.number)
if err != nil {
return err
}
err = m.AttachFlyoverAerialServices(ctx, exec, rel34...)
if err != nil {
return err
}
}
}
}
isPoolsDone, _ := organizationRelPoolsCtx.Value(ctx)
if !isPoolsDone && o.r.Pools != nil {
ctx = organizationRelPoolsCtx.WithValue(ctx, true)
@ -1798,12 +1836,12 @@ func (o *OrganizationTemplate) insertOptRels(ctx context.Context, exec bob.Execu
if r.o.alreadyPersisted {
m.R.Pools = append(m.R.Pools, r.o.Build())
} else {
rel34, err := r.o.CreateMany(ctx, exec, r.number)
rel35, err := r.o.CreateMany(ctx, exec, r.number)
if err != nil {
return err
}
err = m.AttachPools(ctx, exec, rel34...)
err = m.AttachPools(ctx, exec, rel35...)
if err != nil {
return err
}
@ -1818,12 +1856,12 @@ func (o *OrganizationTemplate) insertOptRels(ctx context.Context, exec bob.Execu
if r.o.alreadyPersisted {
m.R.H3Aggregations = append(m.R.H3Aggregations, r.o.Build())
} else {
rel35, err := r.o.CreateMany(ctx, exec, r.number)
rel36, err := r.o.CreateMany(ctx, exec, r.number)
if err != nil {
return err
}
err = m.AttachH3Aggregations(ctx, exec, rel35...)
err = m.AttachH3Aggregations(ctx, exec, rel36...)
if err != nil {
return err
}
@ -1838,12 +1876,12 @@ func (o *OrganizationTemplate) insertOptRels(ctx context.Context, exec bob.Execu
if r.o.alreadyPersisted {
m.R.NoteAudios = append(m.R.NoteAudios, r.o.Build())
} else {
rel36, err := r.o.CreateMany(ctx, exec, r.number)
rel37, err := r.o.CreateMany(ctx, exec, r.number)
if err != nil {
return err
}
err = m.AttachNoteAudios(ctx, exec, rel36...)
err = m.AttachNoteAudios(ctx, exec, rel37...)
if err != nil {
return err
}
@ -1858,12 +1896,12 @@ func (o *OrganizationTemplate) insertOptRels(ctx context.Context, exec bob.Execu
if r.o.alreadyPersisted {
m.R.NoteImages = append(m.R.NoteImages, r.o.Build())
} else {
rel37, err := r.o.CreateMany(ctx, exec, r.number)
rel38, err := r.o.CreateMany(ctx, exec, r.number)
if err != nil {
return err
}
err = m.AttachNoteImages(ctx, exec, rel37...)
err = m.AttachNoteImages(ctx, exec, rel38...)
if err != nil {
return err
}
@ -1877,12 +1915,12 @@ func (o *OrganizationTemplate) insertOptRels(ctx context.Context, exec bob.Execu
if o.r.ArcgisAccountAccount.o.alreadyPersisted {
m.R.ArcgisAccountAccount = o.r.ArcgisAccountAccount.o.Build()
} else {
var rel38 *models.ArcgisAccount
rel38, err = o.r.ArcgisAccountAccount.o.Create(ctx, exec)
var rel39 *models.ArcgisAccount
rel39, err = o.r.ArcgisAccountAccount.o.Create(ctx, exec)
if err != nil {
return err
}
err = m.AttachArcgisAccountAccount(ctx, exec, rel38)
err = m.AttachArcgisAccountAccount(ctx, exec, rel39)
if err != nil {
return err
}
@ -1896,12 +1934,12 @@ func (o *OrganizationTemplate) insertOptRels(ctx context.Context, exec bob.Execu
if o.r.FieldseekerServiceFeatureItemServiceFeature.o.alreadyPersisted {
m.R.FieldseekerServiceFeatureItemServiceFeature = o.r.FieldseekerServiceFeatureItemServiceFeature.o.Build()
} else {
var rel39 *models.ArcgisServiceFeature
rel39, err = o.r.FieldseekerServiceFeatureItemServiceFeature.o.Create(ctx, exec)
var rel40 *models.ArcgisServiceFeature
rel40, err = o.r.FieldseekerServiceFeatureItemServiceFeature.o.Create(ctx, exec)
if err != nil {
return err
}
err = m.AttachFieldseekerServiceFeatureItemServiceFeature(ctx, exec, rel39)
err = m.AttachFieldseekerServiceFeatureItemServiceFeature(ctx, exec, rel40)
if err != nil {
return err
}
@ -1916,12 +1954,12 @@ func (o *OrganizationTemplate) insertOptRels(ctx context.Context, exec bob.Execu
if r.o.alreadyPersisted {
m.R.Nuisances = append(m.R.Nuisances, r.o.Build())
} else {
rel40, err := r.o.CreateMany(ctx, exec, r.number)
rel41, err := r.o.CreateMany(ctx, exec, r.number)
if err != nil {
return err
}
err = m.AttachNuisances(ctx, exec, rel40...)
err = m.AttachNuisances(ctx, exec, rel41...)
if err != nil {
return err
}
@ -1936,12 +1974,12 @@ func (o *OrganizationTemplate) insertOptRels(ctx context.Context, exec bob.Execu
if r.o.alreadyPersisted {
m.R.PublicreportPool = append(m.R.PublicreportPool, r.o.Build())
} else {
rel41, err := r.o.CreateMany(ctx, exec, r.number)
rel42, err := r.o.CreateMany(ctx, exec, r.number)
if err != nil {
return err
}
err = m.AttachPublicreportPool(ctx, exec, rel41...)
err = m.AttachPublicreportPool(ctx, exec, rel42...)
if err != nil {
return err
}
@ -1956,12 +1994,12 @@ func (o *OrganizationTemplate) insertOptRels(ctx context.Context, exec bob.Execu
if r.o.alreadyPersisted {
m.R.Quicks = append(m.R.Quicks, r.o.Build())
} else {
rel42, err := r.o.CreateMany(ctx, exec, r.number)
rel43, err := r.o.CreateMany(ctx, exec, r.number)
if err != nil {
return err
}
err = m.AttachQuicks(ctx, exec, rel42...)
err = m.AttachQuicks(ctx, exec, rel43...)
if err != nil {
return err
}
@ -1976,12 +2014,12 @@ func (o *OrganizationTemplate) insertOptRels(ctx context.Context, exec bob.Execu
if r.o.alreadyPersisted {
m.R.User = append(m.R.User, r.o.Build())
} else {
rel43, err := r.o.CreateMany(ctx, exec, r.number)
rel44, err := r.o.CreateMany(ctx, exec, r.number)
if err != nil {
return err
}
err = m.AttachUser(ctx, exec, rel43...)
err = m.AttachUser(ctx, exec, rel44...)
if err != nil {
return err
}
@ -5479,6 +5517,54 @@ func (m organizationMods) WithoutFiles() OrganizationMod {
})
}
func (m organizationMods) WithFlyoverAerialServices(number int, related *FileuploadFlyoverAerialServiceTemplate) OrganizationMod {
return OrganizationModFunc(func(ctx context.Context, o *OrganizationTemplate) {
o.r.FlyoverAerialServices = []*organizationRFlyoverAerialServicesR{{
number: number,
o: related,
}}
})
}
func (m organizationMods) WithNewFlyoverAerialServices(number int, mods ...FileuploadFlyoverAerialServiceMod) OrganizationMod {
return OrganizationModFunc(func(ctx context.Context, o *OrganizationTemplate) {
related := o.f.NewFileuploadFlyoverAerialServiceWithContext(ctx, mods...)
m.WithFlyoverAerialServices(number, related).Apply(ctx, o)
})
}
func (m organizationMods) AddFlyoverAerialServices(number int, related *FileuploadFlyoverAerialServiceTemplate) OrganizationMod {
return OrganizationModFunc(func(ctx context.Context, o *OrganizationTemplate) {
o.r.FlyoverAerialServices = append(o.r.FlyoverAerialServices, &organizationRFlyoverAerialServicesR{
number: number,
o: related,
})
})
}
func (m organizationMods) AddNewFlyoverAerialServices(number int, mods ...FileuploadFlyoverAerialServiceMod) OrganizationMod {
return OrganizationModFunc(func(ctx context.Context, o *OrganizationTemplate) {
related := o.f.NewFileuploadFlyoverAerialServiceWithContext(ctx, mods...)
m.AddFlyoverAerialServices(number, related).Apply(ctx, o)
})
}
func (m organizationMods) AddExistingFlyoverAerialServices(existingModels ...*models.FileuploadFlyoverAerialService) OrganizationMod {
return OrganizationModFunc(func(ctx context.Context, o *OrganizationTemplate) {
for _, em := range existingModels {
o.r.FlyoverAerialServices = append(o.r.FlyoverAerialServices, &organizationRFlyoverAerialServicesR{
o: o.f.FromExistingFileuploadFlyoverAerialService(em),
})
}
})
}
func (m organizationMods) WithoutFlyoverAerialServices() OrganizationMod {
return OrganizationModFunc(func(ctx context.Context, o *OrganizationTemplate) {
o.r.FlyoverAerialServices = nil
})
}
func (m organizationMods) WithPools(number int, related *FileuploadPoolTemplate) OrganizationMod {
return OrganizationModFunc(func(ctx context.Context, o *OrganizationTemplate) {
o.r.Pools = []*organizationRPoolsR{{

View file

@ -63,6 +63,7 @@ type userR struct {
PublicUserUser []*userRPublicUserUserR
CreatorComplianceReportRequests []*userRCreatorComplianceReportRequestsR
CreatorFiles []*userRCreatorFilesR
CreatorFlyoverAerialServices []*userRCreatorFlyoverAerialServicesR
FileuploadPool []*userRFileuploadPoolR
CreatorNoteAudios []*userRCreatorNoteAudiosR
DeletorNoteAudios []*userRDeletorNoteAudiosR
@ -91,6 +92,10 @@ type userRCreatorFilesR struct {
number int
o *FileuploadFileTemplate
}
type userRCreatorFlyoverAerialServicesR struct {
number int
o *FileuploadFlyoverAerialServiceTemplate
}
type userRFileuploadPoolR struct {
number int
o *FileuploadPoolTemplate
@ -193,6 +198,19 @@ func (t UserTemplate) setModelRels(o *models.User) {
o.R.CreatorFiles = rel
}
if t.r.CreatorFlyoverAerialServices != nil {
rel := models.FileuploadFlyoverAerialServiceSlice{}
for _, r := range t.r.CreatorFlyoverAerialServices {
related := r.o.BuildMany(r.number)
for _, rel := range related {
rel.CreatorID = o.ID // h2
rel.R.CreatorUser = o
}
rel = append(rel, related...)
}
o.R.CreatorFlyoverAerialServices = rel
}
if t.r.FileuploadPool != nil {
rel := models.FileuploadPoolSlice{}
for _, r := range t.r.FileuploadPool {
@ -568,6 +586,26 @@ func (o *UserTemplate) insertOptRels(ctx context.Context, exec bob.Executor, m *
}
}
isCreatorFlyoverAerialServicesDone, _ := userRelCreatorFlyoverAerialServicesCtx.Value(ctx)
if !isCreatorFlyoverAerialServicesDone && o.r.CreatorFlyoverAerialServices != nil {
ctx = userRelCreatorFlyoverAerialServicesCtx.WithValue(ctx, true)
for _, r := range o.r.CreatorFlyoverAerialServices {
if r.o.alreadyPersisted {
m.R.CreatorFlyoverAerialServices = append(m.R.CreatorFlyoverAerialServices, r.o.Build())
} else {
rel4, err := r.o.CreateMany(ctx, exec, r.number)
if err != nil {
return err
}
err = m.AttachCreatorFlyoverAerialServices(ctx, exec, rel4...)
if err != nil {
return err
}
}
}
}
isFileuploadPoolDone, _ := userRelFileuploadPoolCtx.Value(ctx)
if !isFileuploadPoolDone && o.r.FileuploadPool != nil {
ctx = userRelFileuploadPoolCtx.WithValue(ctx, true)
@ -575,12 +613,12 @@ func (o *UserTemplate) insertOptRels(ctx context.Context, exec bob.Executor, m *
if r.o.alreadyPersisted {
m.R.FileuploadPool = append(m.R.FileuploadPool, r.o.Build())
} else {
rel4, err := r.o.CreateMany(ctx, exec, r.number)
rel5, err := r.o.CreateMany(ctx, exec, r.number)
if err != nil {
return err
}
err = m.AttachFileuploadPool(ctx, exec, rel4...)
err = m.AttachFileuploadPool(ctx, exec, rel5...)
if err != nil {
return err
}
@ -595,12 +633,12 @@ func (o *UserTemplate) insertOptRels(ctx context.Context, exec bob.Executor, m *
if r.o.alreadyPersisted {
m.R.CreatorNoteAudios = append(m.R.CreatorNoteAudios, r.o.Build())
} else {
rel5, err := r.o.CreateMany(ctx, exec, r.number)
rel6, err := r.o.CreateMany(ctx, exec, r.number)
if err != nil {
return err
}
err = m.AttachCreatorNoteAudios(ctx, exec, rel5...)
err = m.AttachCreatorNoteAudios(ctx, exec, rel6...)
if err != nil {
return err
}
@ -615,12 +653,12 @@ func (o *UserTemplate) insertOptRels(ctx context.Context, exec bob.Executor, m *
if r.o.alreadyPersisted {
m.R.DeletorNoteAudios = append(m.R.DeletorNoteAudios, r.o.Build())
} else {
rel6, err := r.o.CreateMany(ctx, exec, r.number)
rel7, err := r.o.CreateMany(ctx, exec, r.number)
if err != nil {
return err
}
err = m.AttachDeletorNoteAudios(ctx, exec, rel6...)
err = m.AttachDeletorNoteAudios(ctx, exec, rel7...)
if err != nil {
return err
}
@ -635,12 +673,12 @@ func (o *UserTemplate) insertOptRels(ctx context.Context, exec bob.Executor, m *
if r.o.alreadyPersisted {
m.R.CreatorNoteImages = append(m.R.CreatorNoteImages, r.o.Build())
} else {
rel7, err := r.o.CreateMany(ctx, exec, r.number)
rel8, err := r.o.CreateMany(ctx, exec, r.number)
if err != nil {
return err
}
err = m.AttachCreatorNoteImages(ctx, exec, rel7...)
err = m.AttachCreatorNoteImages(ctx, exec, rel8...)
if err != nil {
return err
}
@ -655,12 +693,12 @@ func (o *UserTemplate) insertOptRels(ctx context.Context, exec bob.Executor, m *
if r.o.alreadyPersisted {
m.R.DeletorNoteImages = append(m.R.DeletorNoteImages, r.o.Build())
} else {
rel8, err := r.o.CreateMany(ctx, exec, r.number)
rel9, err := r.o.CreateMany(ctx, exec, r.number)
if err != nil {
return err
}
err = m.AttachDeletorNoteImages(ctx, exec, rel8...)
err = m.AttachDeletorNoteImages(ctx, exec, rel9...)
if err != nil {
return err
}
@ -675,12 +713,12 @@ func (o *UserTemplate) insertOptRels(ctx context.Context, exec bob.Executor, m *
if r.o.alreadyPersisted {
m.R.UserNotifications = append(m.R.UserNotifications, r.o.Build())
} else {
rel9, err := r.o.CreateMany(ctx, exec, r.number)
rel10, err := r.o.CreateMany(ctx, exec, r.number)
if err != nil {
return err
}
err = m.AttachUserNotifications(ctx, exec, rel9...)
err = m.AttachUserNotifications(ctx, exec, rel10...)
if err != nil {
return err
}
@ -695,12 +733,12 @@ func (o *UserTemplate) insertOptRels(ctx context.Context, exec bob.Executor, m *
if r.o.alreadyPersisted {
m.R.CreatorPools = append(m.R.CreatorPools, r.o.Build())
} else {
rel10, err := r.o.CreateMany(ctx, exec, r.number)
rel11, err := r.o.CreateMany(ctx, exec, r.number)
if err != nil {
return err
}
err = m.AttachCreatorPools(ctx, exec, rel10...)
err = m.AttachCreatorPools(ctx, exec, rel11...)
if err != nil {
return err
}
@ -715,12 +753,12 @@ func (o *UserTemplate) insertOptRels(ctx context.Context, exec bob.Executor, m *
if r.o.alreadyPersisted {
m.R.CreatorResidents = append(m.R.CreatorResidents, r.o.Build())
} else {
rel11, err := r.o.CreateMany(ctx, exec, r.number)
rel12, err := r.o.CreateMany(ctx, exec, r.number)
if err != nil {
return err
}
err = m.AttachCreatorResidents(ctx, exec, rel11...)
err = m.AttachCreatorResidents(ctx, exec, rel12...)
if err != nil {
return err
}
@ -735,12 +773,12 @@ func (o *UserTemplate) insertOptRels(ctx context.Context, exec bob.Executor, m *
if r.o.alreadyPersisted {
m.R.CreatorSites = append(m.R.CreatorSites, r.o.Build())
} else {
rel12, err := r.o.CreateMany(ctx, exec, r.number)
rel13, err := r.o.CreateMany(ctx, exec, r.number)
if err != nil {
return err
}
err = m.AttachCreatorSites(ctx, exec, rel12...)
err = m.AttachCreatorSites(ctx, exec, rel13...)
if err != nil {
return err
}
@ -762,25 +800,25 @@ func (o *UserTemplate) Create(ctx context.Context, exec bob.Executor) (*models.U
UserMods.WithNewOrganization().Apply(ctx, o)
}
var rel13 *models.Organization
var rel14 *models.Organization
if o.r.Organization.o.alreadyPersisted {
rel13 = o.r.Organization.o.Build()
rel14 = o.r.Organization.o.Build()
} else {
rel13, err = o.r.Organization.o.Create(ctx, exec)
rel14, err = o.r.Organization.o.Create(ctx, exec)
if err != nil {
return nil, err
}
}
opt.OrganizationID = omit.From(rel13.ID)
opt.OrganizationID = omit.From(rel14.ID)
m, err := models.Users.Insert(opt).One(ctx, exec)
if err != nil {
return nil, err
}
m.R.Organization = rel13
m.R.Organization = rel14
if err := o.insertOptRels(ctx, exec, m); err != nil {
return nil, err
@ -1646,6 +1684,54 @@ func (m userMods) WithoutCreatorFiles() UserMod {
})
}
func (m userMods) WithCreatorFlyoverAerialServices(number int, related *FileuploadFlyoverAerialServiceTemplate) UserMod {
return UserModFunc(func(ctx context.Context, o *UserTemplate) {
o.r.CreatorFlyoverAerialServices = []*userRCreatorFlyoverAerialServicesR{{
number: number,
o: related,
}}
})
}
func (m userMods) WithNewCreatorFlyoverAerialServices(number int, mods ...FileuploadFlyoverAerialServiceMod) UserMod {
return UserModFunc(func(ctx context.Context, o *UserTemplate) {
related := o.f.NewFileuploadFlyoverAerialServiceWithContext(ctx, mods...)
m.WithCreatorFlyoverAerialServices(number, related).Apply(ctx, o)
})
}
func (m userMods) AddCreatorFlyoverAerialServices(number int, related *FileuploadFlyoverAerialServiceTemplate) UserMod {
return UserModFunc(func(ctx context.Context, o *UserTemplate) {
o.r.CreatorFlyoverAerialServices = append(o.r.CreatorFlyoverAerialServices, &userRCreatorFlyoverAerialServicesR{
number: number,
o: related,
})
})
}
func (m userMods) AddNewCreatorFlyoverAerialServices(number int, mods ...FileuploadFlyoverAerialServiceMod) UserMod {
return UserModFunc(func(ctx context.Context, o *UserTemplate) {
related := o.f.NewFileuploadFlyoverAerialServiceWithContext(ctx, mods...)
m.AddCreatorFlyoverAerialServices(number, related).Apply(ctx, o)
})
}
func (m userMods) AddExistingCreatorFlyoverAerialServices(existingModels ...*models.FileuploadFlyoverAerialService) UserMod {
return UserModFunc(func(ctx context.Context, o *UserTemplate) {
for _, em := range existingModels {
o.r.CreatorFlyoverAerialServices = append(o.r.CreatorFlyoverAerialServices, &userRCreatorFlyoverAerialServicesR{
o: o.f.FromExistingFileuploadFlyoverAerialService(em),
})
}
})
}
func (m userMods) WithoutCreatorFlyoverAerialServices() UserMod {
return UserModFunc(func(ctx context.Context, o *UserTemplate) {
o.r.CreatorFlyoverAerialServices = nil
})
}
func (m userMods) WithFileuploadPool(number int, related *FileuploadPoolTemplate) UserMod {
return UserModFunc(func(ctx context.Context, o *UserTemplate) {
o.r.FileuploadPool = []*userRFileuploadPoolR{{

View file

@ -0,0 +1,18 @@
-- +goose Up
ALTER TYPE fileupload.CSVType ADD VALUE 'Flyover' AFTER 'PoolList';
CREATE TABLE fileupload.flyover_aerial_service (
committed BOOLEAN NOT NULL, -- Whether or not its just proposed before a CSV file is committed
condition fileupload.PoolConditionType NOT NULL,
created TIMESTAMP WITHOUT TIME ZONE NOT NULL,
creator_id INTEGER REFERENCES user_(id) NOT NULL,
csv_file INTEGER REFERENCES fileupload.csv(file_id) NOT NULL,
deleted TIMESTAMP WITHOUT TIME ZONE,
geom geometry(Point, 4326),
h3cell h3index,
id SERIAL,
organization_id INTEGER REFERENCES organization(id) NOT NULL,
PRIMARY KEY (id)
);
-- +goose Down
DROP TABLE fileupload.flyover_aerial_services;
ALTER TYPE fileupload.CSVType DROP VALUE 'Flyover';

View file

@ -0,0 +1,3 @@
-- +goose Up
CREATE INDEX idx_address_geom ON address USING GIST (geom);
CREATE INDEX idx_parcel_geometry ON parcel USING GIST (geometry);

View file

@ -0,0 +1,16 @@
-- +goose Up
-- +goose StatementBegin
CREATE OR REPLACE FUNCTION generate_alphanumeric_code(code_length INTEGER DEFAULT 8)
RETURNS TEXT AS $$
DECLARE
chars TEXT := 'ABCDEFGHJKMNPQRSTUVWXYZ23456789';
result TEXT := '';
i INTEGER;
BEGIN
FOR i IN 1..code_length LOOP
result := result || substr(chars, floor(random() * length(chars) + 1)::INTEGER, 1);
END LOOP;
RETURN result;
END;
$$ LANGUAGE plpgsql;
-- +goose StatementEnd

View file

@ -84,6 +84,7 @@ type joins[Q dialect.Joinable] struct {
FileuploadErrorCSVS joinSet[fileuploadErrorCSVJoins[Q]]
FileuploadErrorFiles joinSet[fileuploadErrorFileJoins[Q]]
FileuploadFiles joinSet[fileuploadFileJoins[Q]]
FileuploadFlyoverAerialServices joinSet[fileuploadFlyoverAerialServiceJoins[Q]]
FileuploadPools joinSet[fileuploadPoolJoins[Q]]
H3Aggregations joinSet[h3AggregationJoins[Q]]
NoteAudios joinSet[noteAudioJoins[Q]]
@ -177,6 +178,7 @@ func getJoins[Q dialect.Joinable]() joins[Q] {
FileuploadErrorCSVS: buildJoinSet[fileuploadErrorCSVJoins[Q]](FileuploadErrorCSVS.Columns, buildFileuploadErrorCSVJoins),
FileuploadErrorFiles: buildJoinSet[fileuploadErrorFileJoins[Q]](FileuploadErrorFiles.Columns, buildFileuploadErrorFileJoins),
FileuploadFiles: buildJoinSet[fileuploadFileJoins[Q]](FileuploadFiles.Columns, buildFileuploadFileJoins),
FileuploadFlyoverAerialServices: buildJoinSet[fileuploadFlyoverAerialServiceJoins[Q]](FileuploadFlyoverAerialServices.Columns, buildFileuploadFlyoverAerialServiceJoins),
FileuploadPools: buildJoinSet[fileuploadPoolJoins[Q]](FileuploadPools.Columns, buildFileuploadPoolJoins),
H3Aggregations: buildJoinSet[h3AggregationJoins[Q]](H3Aggregations.Columns, buildH3AggregationJoins),
NoteAudios: buildJoinSet[noteAudioJoins[Q]](NoteAudios.Columns, buildNoteAudioJoins),

View file

@ -69,6 +69,7 @@ type preloaders struct {
FileuploadErrorCSV fileuploadErrorCSVPreloader
FileuploadErrorFile fileuploadErrorFilePreloader
FileuploadFile fileuploadFilePreloader
FileuploadFlyoverAerialService fileuploadFlyoverAerialServicePreloader
FileuploadPool fileuploadPoolPreloader
H3Aggregation h3AggregationPreloader
NoteAudio noteAudioPreloader
@ -154,6 +155,7 @@ func getPreloaders() preloaders {
FileuploadErrorCSV: buildFileuploadErrorCSVPreloader(),
FileuploadErrorFile: buildFileuploadErrorFilePreloader(),
FileuploadFile: buildFileuploadFilePreloader(),
FileuploadFlyoverAerialService: buildFileuploadFlyoverAerialServicePreloader(),
FileuploadPool: buildFileuploadPoolPreloader(),
H3Aggregation: buildH3AggregationPreloader(),
NoteAudio: buildNoteAudioPreloader(),
@ -245,6 +247,7 @@ type thenLoaders[Q orm.Loadable] struct {
FileuploadErrorCSV fileuploadErrorCSVThenLoader[Q]
FileuploadErrorFile fileuploadErrorFileThenLoader[Q]
FileuploadFile fileuploadFileThenLoader[Q]
FileuploadFlyoverAerialService fileuploadFlyoverAerialServiceThenLoader[Q]
FileuploadPool fileuploadPoolThenLoader[Q]
H3Aggregation h3AggregationThenLoader[Q]
NoteAudio noteAudioThenLoader[Q]
@ -330,6 +333,7 @@ func getThenLoaders[Q orm.Loadable]() thenLoaders[Q] {
FileuploadErrorCSV: buildFileuploadErrorCSVThenLoader[Q](),
FileuploadErrorFile: buildFileuploadErrorFileThenLoader[Q](),
FileuploadFile: buildFileuploadFileThenLoader[Q](),
FileuploadFlyoverAerialService: buildFileuploadFlyoverAerialServiceThenLoader[Q](),
FileuploadPool: buildFileuploadPoolThenLoader[Q](),
H3Aggregation: buildH3AggregationThenLoader[Q](),
NoteAudio: buildNoteAudioThenLoader[Q](),

View file

@ -70,6 +70,7 @@ func Where[Q psql.Filterable]() struct {
FileuploadErrorCSVS fileuploadErrorCSVWhere[Q]
FileuploadErrorFiles fileuploadErrorFileWhere[Q]
FileuploadFiles fileuploadFileWhere[Q]
FileuploadFlyoverAerialServices fileuploadFlyoverAerialServiceWhere[Q]
FileuploadPools fileuploadPoolWhere[Q]
GeographyColumns geographyColumnWhere[Q]
GeometryColumns geometryColumnWhere[Q]
@ -162,6 +163,7 @@ func Where[Q psql.Filterable]() struct {
FileuploadErrorCSVS fileuploadErrorCSVWhere[Q]
FileuploadErrorFiles fileuploadErrorFileWhere[Q]
FileuploadFiles fileuploadFileWhere[Q]
FileuploadFlyoverAerialServices fileuploadFlyoverAerialServiceWhere[Q]
FileuploadPools fileuploadPoolWhere[Q]
GeographyColumns geographyColumnWhere[Q]
GeometryColumns geometryColumnWhere[Q]
@ -253,6 +255,7 @@ func Where[Q psql.Filterable]() struct {
FileuploadErrorCSVS: buildFileuploadErrorCSVWhere[Q](FileuploadErrorCSVS.Columns),
FileuploadErrorFiles: buildFileuploadErrorFileWhere[Q](FileuploadErrorFiles.Columns),
FileuploadFiles: buildFileuploadFileWhere[Q](FileuploadFiles.Columns),
FileuploadFlyoverAerialServices: buildFileuploadFlyoverAerialServiceWhere[Q](FileuploadFlyoverAerialServices.Columns),
FileuploadPools: buildFileuploadPoolWhere[Q](FileuploadPools.Columns),
GeographyColumns: buildGeographyColumnWhere[Q](GeographyColumns.Columns),
GeometryColumns: buildGeometryColumnWhere[Q](GeometryColumns.Columns),

View file

@ -49,9 +49,10 @@ type FileuploadCSVSQuery = *psql.ViewQuery[*FileuploadCSV, FileuploadCSVSlice]
// fileuploadCSVR is where relationships are stored.
type fileuploadCSVR struct {
File *FileuploadFile // fileupload.csv.csv_file_id_fkey
CSVFileErrorCSVS FileuploadErrorCSVSlice // fileupload.error_csv.error_csv_csv_file_id_fkey
CSVFilePools FileuploadPoolSlice // fileupload.pool.pool_csv_file_fkey
File *FileuploadFile // fileupload.csv.csv_file_id_fkey
CSVFileErrorCSVS FileuploadErrorCSVSlice // fileupload.error_csv.error_csv_csv_file_id_fkey
CSVFileFlyoverAerialServices FileuploadFlyoverAerialServiceSlice // fileupload.flyover_aerial_service.flyover_aerial_service_csv_file_fkey
CSVFilePools FileuploadPoolSlice // fileupload.pool.pool_csv_file_fkey
}
func buildFileuploadCSVColumns(alias string) fileuploadCSVColumns {
@ -470,6 +471,30 @@ func (os FileuploadCSVSlice) CSVFileErrorCSVS(mods ...bob.Mod[*dialect.SelectQue
)...)
}
// CSVFileFlyoverAerialServices starts a query for related objects on fileupload.flyover_aerial_service
func (o *FileuploadCSV) CSVFileFlyoverAerialServices(mods ...bob.Mod[*dialect.SelectQuery]) FileuploadFlyoverAerialServicesQuery {
return FileuploadFlyoverAerialServices.Query(append(mods,
sm.Where(FileuploadFlyoverAerialServices.Columns.CSVFile.EQ(psql.Arg(o.FileID))),
)...)
}
func (os FileuploadCSVSlice) CSVFileFlyoverAerialServices(mods ...bob.Mod[*dialect.SelectQuery]) FileuploadFlyoverAerialServicesQuery {
pkFileID := make(pgtypes.Array[int32], 0, len(os))
for _, o := range os {
if o == nil {
continue
}
pkFileID = append(pkFileID, o.FileID)
}
PKArgExpr := psql.Select(sm.Columns(
psql.F("unnest", psql.Cast(psql.Arg(pkFileID), "integer[]")),
))
return FileuploadFlyoverAerialServices.Query(append(mods,
sm.Where(psql.Group(FileuploadFlyoverAerialServices.Columns.CSVFile).OP("IN", PKArgExpr)),
)...)
}
// CSVFilePools starts a query for related objects on fileupload.pool
func (o *FileuploadCSV) CSVFilePools(mods ...bob.Mod[*dialect.SelectQuery]) FileuploadPoolsQuery {
return FileuploadPools.Query(append(mods,
@ -610,6 +635,74 @@ func (fileuploadCSV0 *FileuploadCSV) AttachCSVFileErrorCSVS(ctx context.Context,
return nil
}
func insertFileuploadCSVCSVFileFlyoverAerialServices0(ctx context.Context, exec bob.Executor, fileuploadFlyoverAerialServices1 []*FileuploadFlyoverAerialServiceSetter, fileuploadCSV0 *FileuploadCSV) (FileuploadFlyoverAerialServiceSlice, error) {
for i := range fileuploadFlyoverAerialServices1 {
fileuploadFlyoverAerialServices1[i].CSVFile = omit.From(fileuploadCSV0.FileID)
}
ret, err := FileuploadFlyoverAerialServices.Insert(bob.ToMods(fileuploadFlyoverAerialServices1...)).All(ctx, exec)
if err != nil {
return ret, fmt.Errorf("insertFileuploadCSVCSVFileFlyoverAerialServices0: %w", err)
}
return ret, nil
}
func attachFileuploadCSVCSVFileFlyoverAerialServices0(ctx context.Context, exec bob.Executor, count int, fileuploadFlyoverAerialServices1 FileuploadFlyoverAerialServiceSlice, fileuploadCSV0 *FileuploadCSV) (FileuploadFlyoverAerialServiceSlice, error) {
setter := &FileuploadFlyoverAerialServiceSetter{
CSVFile: omit.From(fileuploadCSV0.FileID),
}
err := fileuploadFlyoverAerialServices1.UpdateAll(ctx, exec, *setter)
if err != nil {
return nil, fmt.Errorf("attachFileuploadCSVCSVFileFlyoverAerialServices0: %w", err)
}
return fileuploadFlyoverAerialServices1, nil
}
func (fileuploadCSV0 *FileuploadCSV) InsertCSVFileFlyoverAerialServices(ctx context.Context, exec bob.Executor, related ...*FileuploadFlyoverAerialServiceSetter) error {
if len(related) == 0 {
return nil
}
var err error
fileuploadFlyoverAerialServices1, err := insertFileuploadCSVCSVFileFlyoverAerialServices0(ctx, exec, related, fileuploadCSV0)
if err != nil {
return err
}
fileuploadCSV0.R.CSVFileFlyoverAerialServices = append(fileuploadCSV0.R.CSVFileFlyoverAerialServices, fileuploadFlyoverAerialServices1...)
for _, rel := range fileuploadFlyoverAerialServices1 {
rel.R.CSVFileCSV = fileuploadCSV0
}
return nil
}
func (fileuploadCSV0 *FileuploadCSV) AttachCSVFileFlyoverAerialServices(ctx context.Context, exec bob.Executor, related ...*FileuploadFlyoverAerialService) error {
if len(related) == 0 {
return nil
}
var err error
fileuploadFlyoverAerialServices1 := FileuploadFlyoverAerialServiceSlice(related)
_, err = attachFileuploadCSVCSVFileFlyoverAerialServices0(ctx, exec, len(related), fileuploadFlyoverAerialServices1, fileuploadCSV0)
if err != nil {
return err
}
fileuploadCSV0.R.CSVFileFlyoverAerialServices = append(fileuploadCSV0.R.CSVFileFlyoverAerialServices, fileuploadFlyoverAerialServices1...)
for _, rel := range related {
rel.R.CSVFileCSV = fileuploadCSV0
}
return nil
}
func insertFileuploadCSVCSVFilePools0(ctx context.Context, exec bob.Executor, fileuploadPools1 []*FileuploadPoolSetter, fileuploadCSV0 *FileuploadCSV) (FileuploadPoolSlice, error) {
for i := range fileuploadPools1 {
fileuploadPools1[i].CSVFile = omit.From(fileuploadCSV0.FileID)
@ -724,6 +817,20 @@ func (o *FileuploadCSV) Preload(name string, retrieved any) error {
o.R.CSVFileErrorCSVS = rels
for _, rel := range rels {
if rel != nil {
rel.R.CSVFileCSV = o
}
}
return nil
case "CSVFileFlyoverAerialServices":
rels, ok := retrieved.(FileuploadFlyoverAerialServiceSlice)
if !ok {
return fmt.Errorf("fileuploadCSV cannot load %T as %q", retrieved, name)
}
o.R.CSVFileFlyoverAerialServices = rels
for _, rel := range rels {
if rel != nil {
rel.R.CSVFileCSV = o
@ -772,9 +879,10 @@ func buildFileuploadCSVPreloader() fileuploadCSVPreloader {
}
type fileuploadCSVThenLoader[Q orm.Loadable] struct {
File func(...bob.Mod[*dialect.SelectQuery]) orm.Loader[Q]
CSVFileErrorCSVS func(...bob.Mod[*dialect.SelectQuery]) orm.Loader[Q]
CSVFilePools func(...bob.Mod[*dialect.SelectQuery]) orm.Loader[Q]
File func(...bob.Mod[*dialect.SelectQuery]) orm.Loader[Q]
CSVFileErrorCSVS func(...bob.Mod[*dialect.SelectQuery]) orm.Loader[Q]
CSVFileFlyoverAerialServices func(...bob.Mod[*dialect.SelectQuery]) orm.Loader[Q]
CSVFilePools func(...bob.Mod[*dialect.SelectQuery]) orm.Loader[Q]
}
func buildFileuploadCSVThenLoader[Q orm.Loadable]() fileuploadCSVThenLoader[Q] {
@ -784,6 +892,9 @@ func buildFileuploadCSVThenLoader[Q orm.Loadable]() fileuploadCSVThenLoader[Q] {
type CSVFileErrorCSVSLoadInterface interface {
LoadCSVFileErrorCSVS(context.Context, bob.Executor, ...bob.Mod[*dialect.SelectQuery]) error
}
type CSVFileFlyoverAerialServicesLoadInterface interface {
LoadCSVFileFlyoverAerialServices(context.Context, bob.Executor, ...bob.Mod[*dialect.SelectQuery]) error
}
type CSVFilePoolsLoadInterface interface {
LoadCSVFilePools(context.Context, bob.Executor, ...bob.Mod[*dialect.SelectQuery]) error
}
@ -801,6 +912,12 @@ func buildFileuploadCSVThenLoader[Q orm.Loadable]() fileuploadCSVThenLoader[Q] {
return retrieved.LoadCSVFileErrorCSVS(ctx, exec, mods...)
},
),
CSVFileFlyoverAerialServices: thenLoadBuilder[Q](
"CSVFileFlyoverAerialServices",
func(ctx context.Context, exec bob.Executor, retrieved CSVFileFlyoverAerialServicesLoadInterface, mods ...bob.Mod[*dialect.SelectQuery]) error {
return retrieved.LoadCSVFileFlyoverAerialServices(ctx, exec, mods...)
},
),
CSVFilePools: thenLoadBuilder[Q](
"CSVFilePools",
func(ctx context.Context, exec bob.Executor, retrieved CSVFilePoolsLoadInterface, mods ...bob.Mod[*dialect.SelectQuery]) error {
@ -923,6 +1040,67 @@ func (os FileuploadCSVSlice) LoadCSVFileErrorCSVS(ctx context.Context, exec bob.
return nil
}
// LoadCSVFileFlyoverAerialServices loads the fileuploadCSV's CSVFileFlyoverAerialServices into the .R struct
func (o *FileuploadCSV) LoadCSVFileFlyoverAerialServices(ctx context.Context, exec bob.Executor, mods ...bob.Mod[*dialect.SelectQuery]) error {
if o == nil {
return nil
}
// Reset the relationship
o.R.CSVFileFlyoverAerialServices = nil
related, err := o.CSVFileFlyoverAerialServices(mods...).All(ctx, exec)
if err != nil {
return err
}
for _, rel := range related {
rel.R.CSVFileCSV = o
}
o.R.CSVFileFlyoverAerialServices = related
return nil
}
// LoadCSVFileFlyoverAerialServices loads the fileuploadCSV's CSVFileFlyoverAerialServices into the .R struct
func (os FileuploadCSVSlice) LoadCSVFileFlyoverAerialServices(ctx context.Context, exec bob.Executor, mods ...bob.Mod[*dialect.SelectQuery]) error {
if len(os) == 0 {
return nil
}
fileuploadFlyoverAerialServices, err := os.CSVFileFlyoverAerialServices(mods...).All(ctx, exec)
if err != nil {
return err
}
for _, o := range os {
if o == nil {
continue
}
o.R.CSVFileFlyoverAerialServices = nil
}
for _, o := range os {
if o == nil {
continue
}
for _, rel := range fileuploadFlyoverAerialServices {
if !(o.FileID == rel.CSVFile) {
continue
}
rel.R.CSVFileCSV = o
o.R.CSVFileFlyoverAerialServices = append(o.R.CSVFileFlyoverAerialServices, rel)
}
}
return nil
}
// LoadCSVFilePools loads the fileuploadCSV's CSVFilePools into the .R struct
func (o *FileuploadCSV) LoadCSVFilePools(ctx context.Context, exec bob.Executor, mods ...bob.Mod[*dialect.SelectQuery]) error {
if o == nil {
@ -986,8 +1164,9 @@ func (os FileuploadCSVSlice) LoadCSVFilePools(ctx context.Context, exec bob.Exec
// fileuploadCSVC is where relationship counts are stored.
type fileuploadCSVC struct {
CSVFileErrorCSVS *int64
CSVFilePools *int64
CSVFileErrorCSVS *int64
CSVFileFlyoverAerialServices *int64
CSVFilePools *int64
}
// PreloadCount sets a count in the C struct by name
@ -999,6 +1178,8 @@ func (o *FileuploadCSV) PreloadCount(name string, count int64) error {
switch name {
case "CSVFileErrorCSVS":
o.C.CSVFileErrorCSVS = &count
case "CSVFileFlyoverAerialServices":
o.C.CSVFileFlyoverAerialServices = &count
case "CSVFilePools":
o.C.CSVFilePools = &count
}
@ -1006,8 +1187,9 @@ func (o *FileuploadCSV) PreloadCount(name string, count int64) error {
}
type fileuploadCSVCountPreloader struct {
CSVFileErrorCSVS func(...bob.Mod[*dialect.SelectQuery]) psql.Preloader
CSVFilePools func(...bob.Mod[*dialect.SelectQuery]) psql.Preloader
CSVFileErrorCSVS func(...bob.Mod[*dialect.SelectQuery]) psql.Preloader
CSVFileFlyoverAerialServices func(...bob.Mod[*dialect.SelectQuery]) psql.Preloader
CSVFilePools func(...bob.Mod[*dialect.SelectQuery]) psql.Preloader
}
func buildFileuploadCSVCountPreloader() fileuploadCSVCountPreloader {
@ -1029,6 +1211,23 @@ func buildFileuploadCSVCountPreloader() fileuploadCSVCountPreloader {
return psql.Group(psql.Select(subqueryMods...).Expression)
})
},
CSVFileFlyoverAerialServices: func(mods ...bob.Mod[*dialect.SelectQuery]) psql.Preloader {
return countPreloader[*FileuploadCSV]("CSVFileFlyoverAerialServices", func(parent string) bob.Expression {
// Build a correlated subquery: (SELECT COUNT(*) FROM related WHERE fk = parent.pk)
if parent == "" {
parent = FileuploadCSVS.Alias()
}
subqueryMods := []bob.Mod[*dialect.SelectQuery]{
sm.Columns(psql.Raw("count(*)")),
sm.From(FileuploadFlyoverAerialServices.Name()),
sm.Where(psql.Quote(FileuploadFlyoverAerialServices.Alias(), "csv_file").EQ(psql.Quote(parent, "file_id"))),
}
subqueryMods = append(subqueryMods, mods...)
return psql.Group(psql.Select(subqueryMods...).Expression)
})
},
CSVFilePools: func(mods ...bob.Mod[*dialect.SelectQuery]) psql.Preloader {
return countPreloader[*FileuploadCSV]("CSVFilePools", func(parent string) bob.Expression {
// Build a correlated subquery: (SELECT COUNT(*) FROM related WHERE fk = parent.pk)
@ -1050,14 +1249,18 @@ func buildFileuploadCSVCountPreloader() fileuploadCSVCountPreloader {
}
type fileuploadCSVCountThenLoader[Q orm.Loadable] struct {
CSVFileErrorCSVS func(...bob.Mod[*dialect.SelectQuery]) orm.Loader[Q]
CSVFilePools func(...bob.Mod[*dialect.SelectQuery]) orm.Loader[Q]
CSVFileErrorCSVS func(...bob.Mod[*dialect.SelectQuery]) orm.Loader[Q]
CSVFileFlyoverAerialServices func(...bob.Mod[*dialect.SelectQuery]) orm.Loader[Q]
CSVFilePools func(...bob.Mod[*dialect.SelectQuery]) orm.Loader[Q]
}
func buildFileuploadCSVCountThenLoader[Q orm.Loadable]() fileuploadCSVCountThenLoader[Q] {
type CSVFileErrorCSVSCountInterface interface {
LoadCountCSVFileErrorCSVS(context.Context, bob.Executor, ...bob.Mod[*dialect.SelectQuery]) error
}
type CSVFileFlyoverAerialServicesCountInterface interface {
LoadCountCSVFileFlyoverAerialServices(context.Context, bob.Executor, ...bob.Mod[*dialect.SelectQuery]) error
}
type CSVFilePoolsCountInterface interface {
LoadCountCSVFilePools(context.Context, bob.Executor, ...bob.Mod[*dialect.SelectQuery]) error
}
@ -1069,6 +1272,12 @@ func buildFileuploadCSVCountThenLoader[Q orm.Loadable]() fileuploadCSVCountThenL
return retrieved.LoadCountCSVFileErrorCSVS(ctx, exec, mods...)
},
),
CSVFileFlyoverAerialServices: countThenLoadBuilder[Q](
"CSVFileFlyoverAerialServices",
func(ctx context.Context, exec bob.Executor, retrieved CSVFileFlyoverAerialServicesCountInterface, mods ...bob.Mod[*dialect.SelectQuery]) error {
return retrieved.LoadCountCSVFileFlyoverAerialServices(ctx, exec, mods...)
},
),
CSVFilePools: countThenLoadBuilder[Q](
"CSVFilePools",
func(ctx context.Context, exec bob.Executor, retrieved CSVFilePoolsCountInterface, mods ...bob.Mod[*dialect.SelectQuery]) error {
@ -1108,6 +1317,36 @@ func (os FileuploadCSVSlice) LoadCountCSVFileErrorCSVS(ctx context.Context, exec
return nil
}
// LoadCountCSVFileFlyoverAerialServices loads the count of CSVFileFlyoverAerialServices into the C struct
func (o *FileuploadCSV) LoadCountCSVFileFlyoverAerialServices(ctx context.Context, exec bob.Executor, mods ...bob.Mod[*dialect.SelectQuery]) error {
if o == nil {
return nil
}
count, err := o.CSVFileFlyoverAerialServices(mods...).Count(ctx, exec)
if err != nil {
return err
}
o.C.CSVFileFlyoverAerialServices = &count
return nil
}
// LoadCountCSVFileFlyoverAerialServices loads the count of CSVFileFlyoverAerialServices for a slice
func (os FileuploadCSVSlice) LoadCountCSVFileFlyoverAerialServices(ctx context.Context, exec bob.Executor, mods ...bob.Mod[*dialect.SelectQuery]) error {
if len(os) == 0 {
return nil
}
for _, o := range os {
if err := o.LoadCountCSVFileFlyoverAerialServices(ctx, exec, mods...); err != nil {
return err
}
}
return nil
}
// LoadCountCSVFilePools loads the count of CSVFilePools into the C struct
func (o *FileuploadCSV) LoadCountCSVFilePools(ctx context.Context, exec bob.Executor, mods ...bob.Mod[*dialect.SelectQuery]) error {
if o == nil {
@ -1139,10 +1378,11 @@ func (os FileuploadCSVSlice) LoadCountCSVFilePools(ctx context.Context, exec bob
}
type fileuploadCSVJoins[Q dialect.Joinable] struct {
typ string
File modAs[Q, fileuploadFileColumns]
CSVFileErrorCSVS modAs[Q, fileuploadErrorCSVColumns]
CSVFilePools modAs[Q, fileuploadPoolColumns]
typ string
File modAs[Q, fileuploadFileColumns]
CSVFileErrorCSVS modAs[Q, fileuploadErrorCSVColumns]
CSVFileFlyoverAerialServices modAs[Q, fileuploadFlyoverAerialServiceColumns]
CSVFilePools modAs[Q, fileuploadPoolColumns]
}
func (j fileuploadCSVJoins[Q]) aliasedAs(alias string) fileuploadCSVJoins[Q] {
@ -1180,6 +1420,20 @@ func buildFileuploadCSVJoins[Q dialect.Joinable](cols fileuploadCSVColumns, typ
return mods
},
},
CSVFileFlyoverAerialServices: modAs[Q, fileuploadFlyoverAerialServiceColumns]{
c: FileuploadFlyoverAerialServices.Columns,
f: func(to fileuploadFlyoverAerialServiceColumns) bob.Mod[Q] {
mods := make(mods.QueryMods[Q], 0, 1)
{
mods = append(mods, dialect.Join[Q](typ, FileuploadFlyoverAerialServices.Name().As(to.Alias())).On(
to.CSVFile.EQ(cols.FileID),
))
}
return mods
},
},
CSVFilePools: modAs[Q, fileuploadPoolColumns]{
c: FileuploadPools.Columns,
f: func(to fileuploadPoolColumns) bob.Mod[Q] {

File diff suppressed because it is too large Load diff

View file

@ -113,6 +113,7 @@ type organizationR struct {
Zones2s FieldseekerZones2Slice // fieldseeker.zones2.zones2_organization_id_fkey
FieldseekerSyncs FieldseekerSyncSlice // fieldseeker_sync.fieldseeker_sync_organization_id_fkey
Files FileuploadFileSlice // fileupload.file.file_organization_id_fkey
FlyoverAerialServices FileuploadFlyoverAerialServiceSlice // fileupload.flyover_aerial_service.flyover_aerial_service_organization_id_fkey
Pools FileuploadPoolSlice // fileupload.pool.pool_organization_id_fkey
H3Aggregations H3AggregationSlice // h3_aggregation.h3_aggregation_organization_id_fkey
NoteAudios NoteAudioSlice // note_audio.note_audio_organization_id_fkey
@ -1735,6 +1736,30 @@ func (os OrganizationSlice) Files(mods ...bob.Mod[*dialect.SelectQuery]) Fileupl
)...)
}
// FlyoverAerialServices starts a query for related objects on fileupload.flyover_aerial_service
func (o *Organization) FlyoverAerialServices(mods ...bob.Mod[*dialect.SelectQuery]) FileuploadFlyoverAerialServicesQuery {
return FileuploadFlyoverAerialServices.Query(append(mods,
sm.Where(FileuploadFlyoverAerialServices.Columns.OrganizationID.EQ(psql.Arg(o.ID))),
)...)
}
func (os OrganizationSlice) FlyoverAerialServices(mods ...bob.Mod[*dialect.SelectQuery]) FileuploadFlyoverAerialServicesQuery {
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 FileuploadFlyoverAerialServices.Query(append(mods,
sm.Where(psql.Group(FileuploadFlyoverAerialServices.Columns.OrganizationID).OP("IN", PKArgExpr)),
)...)
}
// Pools starts a query for related objects on fileupload.pool
func (o *Organization) Pools(mods ...bob.Mod[*dialect.SelectQuery]) FileuploadPoolsQuery {
return FileuploadPools.Query(append(mods,
@ -4281,6 +4306,74 @@ func (organization0 *Organization) AttachFiles(ctx context.Context, exec bob.Exe
return nil
}
func insertOrganizationFlyoverAerialServices0(ctx context.Context, exec bob.Executor, fileuploadFlyoverAerialServices1 []*FileuploadFlyoverAerialServiceSetter, organization0 *Organization) (FileuploadFlyoverAerialServiceSlice, error) {
for i := range fileuploadFlyoverAerialServices1 {
fileuploadFlyoverAerialServices1[i].OrganizationID = omit.From(organization0.ID)
}
ret, err := FileuploadFlyoverAerialServices.Insert(bob.ToMods(fileuploadFlyoverAerialServices1...)).All(ctx, exec)
if err != nil {
return ret, fmt.Errorf("insertOrganizationFlyoverAerialServices0: %w", err)
}
return ret, nil
}
func attachOrganizationFlyoverAerialServices0(ctx context.Context, exec bob.Executor, count int, fileuploadFlyoverAerialServices1 FileuploadFlyoverAerialServiceSlice, organization0 *Organization) (FileuploadFlyoverAerialServiceSlice, error) {
setter := &FileuploadFlyoverAerialServiceSetter{
OrganizationID: omit.From(organization0.ID),
}
err := fileuploadFlyoverAerialServices1.UpdateAll(ctx, exec, *setter)
if err != nil {
return nil, fmt.Errorf("attachOrganizationFlyoverAerialServices0: %w", err)
}
return fileuploadFlyoverAerialServices1, nil
}
func (organization0 *Organization) InsertFlyoverAerialServices(ctx context.Context, exec bob.Executor, related ...*FileuploadFlyoverAerialServiceSetter) error {
if len(related) == 0 {
return nil
}
var err error
fileuploadFlyoverAerialServices1, err := insertOrganizationFlyoverAerialServices0(ctx, exec, related, organization0)
if err != nil {
return err
}
organization0.R.FlyoverAerialServices = append(organization0.R.FlyoverAerialServices, fileuploadFlyoverAerialServices1...)
for _, rel := range fileuploadFlyoverAerialServices1 {
rel.R.Organization = organization0
}
return nil
}
func (organization0 *Organization) AttachFlyoverAerialServices(ctx context.Context, exec bob.Executor, related ...*FileuploadFlyoverAerialService) error {
if len(related) == 0 {
return nil
}
var err error
fileuploadFlyoverAerialServices1 := FileuploadFlyoverAerialServiceSlice(related)
_, err = attachOrganizationFlyoverAerialServices0(ctx, exec, len(related), fileuploadFlyoverAerialServices1, organization0)
if err != nil {
return err
}
organization0.R.FlyoverAerialServices = append(organization0.R.FlyoverAerialServices, fileuploadFlyoverAerialServices1...)
for _, rel := range related {
rel.R.Organization = organization0
}
return nil
}
func insertOrganizationPools0(ctx context.Context, exec bob.Executor, fileuploadPools1 []*FileuploadPoolSetter, organization0 *Organization) (FileuploadPoolSlice, error) {
for i := range fileuploadPools1 {
fileuploadPools1[i].OrganizationID = omit.From(organization0.ID)
@ -5473,6 +5566,20 @@ func (o *Organization) Preload(name string, retrieved any) error {
o.R.Files = rels
for _, rel := range rels {
if rel != nil {
rel.R.Organization = o
}
}
return nil
case "FlyoverAerialServices":
rels, ok := retrieved.(FileuploadFlyoverAerialServiceSlice)
if !ok {
return fmt.Errorf("organization cannot load %T as %q", retrieved, name)
}
o.R.FlyoverAerialServices = rels
for _, rel := range rels {
if rel != nil {
rel.R.Organization = o
@ -5691,6 +5798,7 @@ type organizationThenLoader[Q orm.Loadable] struct {
Zones2s func(...bob.Mod[*dialect.SelectQuery]) orm.Loader[Q]
FieldseekerSyncs func(...bob.Mod[*dialect.SelectQuery]) orm.Loader[Q]
Files func(...bob.Mod[*dialect.SelectQuery]) orm.Loader[Q]
FlyoverAerialServices func(...bob.Mod[*dialect.SelectQuery]) orm.Loader[Q]
Pools func(...bob.Mod[*dialect.SelectQuery]) orm.Loader[Q]
H3Aggregations func(...bob.Mod[*dialect.SelectQuery]) orm.Loader[Q]
NoteAudios func(...bob.Mod[*dialect.SelectQuery]) orm.Loader[Q]
@ -5806,6 +5914,9 @@ func buildOrganizationThenLoader[Q orm.Loadable]() organizationThenLoader[Q] {
type FilesLoadInterface interface {
LoadFiles(context.Context, bob.Executor, ...bob.Mod[*dialect.SelectQuery]) error
}
type FlyoverAerialServicesLoadInterface interface {
LoadFlyoverAerialServices(context.Context, bob.Executor, ...bob.Mod[*dialect.SelectQuery]) error
}
type PoolsLoadInterface interface {
LoadPools(context.Context, bob.Executor, ...bob.Mod[*dialect.SelectQuery]) error
}
@ -6042,6 +6153,12 @@ func buildOrganizationThenLoader[Q orm.Loadable]() organizationThenLoader[Q] {
return retrieved.LoadFiles(ctx, exec, mods...)
},
),
FlyoverAerialServices: thenLoadBuilder[Q](
"FlyoverAerialServices",
func(ctx context.Context, exec bob.Executor, retrieved FlyoverAerialServicesLoadInterface, mods ...bob.Mod[*dialect.SelectQuery]) error {
return retrieved.LoadFlyoverAerialServices(ctx, exec, mods...)
},
),
Pools: thenLoadBuilder[Q](
"Pools",
func(ctx context.Context, exec bob.Executor, retrieved PoolsLoadInterface, mods ...bob.Mod[*dialect.SelectQuery]) error {
@ -8219,6 +8336,67 @@ func (os OrganizationSlice) LoadFiles(ctx context.Context, exec bob.Executor, mo
return nil
}
// LoadFlyoverAerialServices loads the organization's FlyoverAerialServices into the .R struct
func (o *Organization) LoadFlyoverAerialServices(ctx context.Context, exec bob.Executor, mods ...bob.Mod[*dialect.SelectQuery]) error {
if o == nil {
return nil
}
// Reset the relationship
o.R.FlyoverAerialServices = nil
related, err := o.FlyoverAerialServices(mods...).All(ctx, exec)
if err != nil {
return err
}
for _, rel := range related {
rel.R.Organization = o
}
o.R.FlyoverAerialServices = related
return nil
}
// LoadFlyoverAerialServices loads the organization's FlyoverAerialServices into the .R struct
func (os OrganizationSlice) LoadFlyoverAerialServices(ctx context.Context, exec bob.Executor, mods ...bob.Mod[*dialect.SelectQuery]) error {
if len(os) == 0 {
return nil
}
fileuploadFlyoverAerialServices, err := os.FlyoverAerialServices(mods...).All(ctx, exec)
if err != nil {
return err
}
for _, o := range os {
if o == nil {
continue
}
o.R.FlyoverAerialServices = nil
}
for _, o := range os {
if o == nil {
continue
}
for _, rel := range fileuploadFlyoverAerialServices {
if !(o.ID == rel.OrganizationID) {
continue
}
rel.R.Organization = o
o.R.FlyoverAerialServices = append(o.R.FlyoverAerialServices, rel)
}
}
return nil
}
// LoadPools loads the organization's Pools into the .R struct
func (o *Organization) LoadPools(ctx context.Context, exec bob.Executor, mods ...bob.Mod[*dialect.SelectQuery]) error {
if o == nil {
@ -8862,6 +9040,7 @@ type organizationC struct {
Zones2s *int64
FieldseekerSyncs *int64
Files *int64
FlyoverAerialServices *int64
Pools *int64
H3Aggregations *int64
NoteAudios *int64
@ -8947,6 +9126,8 @@ func (o *Organization) PreloadCount(name string, count int64) error {
o.C.FieldseekerSyncs = &count
case "Files":
o.C.Files = &count
case "FlyoverAerialServices":
o.C.FlyoverAerialServices = &count
case "Pools":
o.C.Pools = &count
case "H3Aggregations":
@ -9002,6 +9183,7 @@ type organizationCountPreloader struct {
Zones2s func(...bob.Mod[*dialect.SelectQuery]) psql.Preloader
FieldseekerSyncs func(...bob.Mod[*dialect.SelectQuery]) psql.Preloader
Files func(...bob.Mod[*dialect.SelectQuery]) psql.Preloader
FlyoverAerialServices func(...bob.Mod[*dialect.SelectQuery]) psql.Preloader
Pools func(...bob.Mod[*dialect.SelectQuery]) psql.Preloader
H3Aggregations func(...bob.Mod[*dialect.SelectQuery]) psql.Preloader
NoteAudios func(...bob.Mod[*dialect.SelectQuery]) psql.Preloader
@ -9598,6 +9780,23 @@ func buildOrganizationCountPreloader() organizationCountPreloader {
return psql.Group(psql.Select(subqueryMods...).Expression)
})
},
FlyoverAerialServices: func(mods ...bob.Mod[*dialect.SelectQuery]) psql.Preloader {
return countPreloader[*Organization]("FlyoverAerialServices", func(parent string) bob.Expression {
// Build a correlated subquery: (SELECT COUNT(*) FROM related WHERE fk = parent.pk)
if parent == "" {
parent = Organizations.Alias()
}
subqueryMods := []bob.Mod[*dialect.SelectQuery]{
sm.Columns(psql.Raw("count(*)")),
sm.From(FileuploadFlyoverAerialServices.Name()),
sm.Where(psql.Quote(FileuploadFlyoverAerialServices.Alias(), "organization_id").EQ(psql.Quote(parent, "id"))),
}
subqueryMods = append(subqueryMods, mods...)
return psql.Group(psql.Select(subqueryMods...).Expression)
})
},
Pools: func(mods ...bob.Mod[*dialect.SelectQuery]) psql.Preloader {
return countPreloader[*Organization]("Pools", func(parent string) bob.Expression {
// Build a correlated subquery: (SELECT COUNT(*) FROM related WHERE fk = parent.pk)
@ -9772,6 +9971,7 @@ type organizationCountThenLoader[Q orm.Loadable] struct {
Zones2s func(...bob.Mod[*dialect.SelectQuery]) orm.Loader[Q]
FieldseekerSyncs func(...bob.Mod[*dialect.SelectQuery]) orm.Loader[Q]
Files func(...bob.Mod[*dialect.SelectQuery]) orm.Loader[Q]
FlyoverAerialServices func(...bob.Mod[*dialect.SelectQuery]) orm.Loader[Q]
Pools func(...bob.Mod[*dialect.SelectQuery]) orm.Loader[Q]
H3Aggregations func(...bob.Mod[*dialect.SelectQuery]) orm.Loader[Q]
NoteAudios func(...bob.Mod[*dialect.SelectQuery]) orm.Loader[Q]
@ -9885,6 +10085,9 @@ func buildOrganizationCountThenLoader[Q orm.Loadable]() organizationCountThenLoa
type FilesCountInterface interface {
LoadCountFiles(context.Context, bob.Executor, ...bob.Mod[*dialect.SelectQuery]) error
}
type FlyoverAerialServicesCountInterface interface {
LoadCountFlyoverAerialServices(context.Context, bob.Executor, ...bob.Mod[*dialect.SelectQuery]) error
}
type PoolsCountInterface interface {
LoadCountPools(context.Context, bob.Executor, ...bob.Mod[*dialect.SelectQuery]) error
}
@ -10115,6 +10318,12 @@ func buildOrganizationCountThenLoader[Q orm.Loadable]() organizationCountThenLoa
return retrieved.LoadCountFiles(ctx, exec, mods...)
},
),
FlyoverAerialServices: countThenLoadBuilder[Q](
"FlyoverAerialServices",
func(ctx context.Context, exec bob.Executor, retrieved FlyoverAerialServicesCountInterface, mods ...bob.Mod[*dialect.SelectQuery]) error {
return retrieved.LoadCountFlyoverAerialServices(ctx, exec, mods...)
},
),
Pools: countThenLoadBuilder[Q](
"Pools",
func(ctx context.Context, exec bob.Executor, retrieved PoolsCountInterface, mods ...bob.Mod[*dialect.SelectQuery]) error {
@ -11186,6 +11395,36 @@ func (os OrganizationSlice) LoadCountFiles(ctx context.Context, exec bob.Executo
return nil
}
// LoadCountFlyoverAerialServices loads the count of FlyoverAerialServices into the C struct
func (o *Organization) LoadCountFlyoverAerialServices(ctx context.Context, exec bob.Executor, mods ...bob.Mod[*dialect.SelectQuery]) error {
if o == nil {
return nil
}
count, err := o.FlyoverAerialServices(mods...).Count(ctx, exec)
if err != nil {
return err
}
o.C.FlyoverAerialServices = &count
return nil
}
// LoadCountFlyoverAerialServices loads the count of FlyoverAerialServices for a slice
func (os OrganizationSlice) LoadCountFlyoverAerialServices(ctx context.Context, exec bob.Executor, mods ...bob.Mod[*dialect.SelectQuery]) error {
if len(os) == 0 {
return nil
}
for _, o := range os {
if err := o.LoadCountFlyoverAerialServices(ctx, exec, mods...); err != nil {
return err
}
}
return nil
}
// LoadCountPools loads the count of Pools into the C struct
func (o *Organization) LoadCountPools(ctx context.Context, exec bob.Executor, mods ...bob.Mod[*dialect.SelectQuery]) error {
if o == nil {
@ -11462,6 +11701,7 @@ type organizationJoins[Q dialect.Joinable] struct {
Zones2s modAs[Q, fieldseekerZones2Columns]
FieldseekerSyncs modAs[Q, fieldseekerSyncColumns]
Files modAs[Q, fileuploadFileColumns]
FlyoverAerialServices modAs[Q, fileuploadFlyoverAerialServiceColumns]
Pools modAs[Q, fileuploadPoolColumns]
H3Aggregations modAs[Q, h3AggregationColumns]
NoteAudios modAs[Q, noteAudioColumns]
@ -11973,6 +12213,20 @@ func buildOrganizationJoins[Q dialect.Joinable](cols organizationColumns, typ st
return mods
},
},
FlyoverAerialServices: modAs[Q, fileuploadFlyoverAerialServiceColumns]{
c: FileuploadFlyoverAerialServices.Columns,
f: func(to fileuploadFlyoverAerialServiceColumns) bob.Mod[Q] {
mods := make(mods.QueryMods[Q], 0, 1)
{
mods = append(mods, dialect.Join[Q](typ, FileuploadFlyoverAerialServices.Name().As(to.Alias())).On(
to.OrganizationID.EQ(cols.ID),
))
}
return mods
},
},
Pools: modAs[Q, fileuploadPoolColumns]{
c: FileuploadPools.Columns,
f: func(to fileuploadPoolColumns) bob.Mod[Q] {

View file

@ -58,20 +58,21 @@ type UsersQuery = *psql.ViewQuery[*User, UserSlice]
// userR is where relationships are stored.
type userR struct {
UserOauthTokens ArcgisOauthTokenSlice // arcgis.oauth_token.oauth_token_user_id_fkey
PublicUserUser ArcgisUserSlice // arcgis.user_.user__public_user_id_fkey
CreatorComplianceReportRequests ComplianceReportRequestSlice // compliance_report_request.compliance_report_request_creator_fkey
CreatorFiles FileuploadFileSlice // fileupload.file.file_creator_id_fkey
FileuploadPool FileuploadPoolSlice // fileupload.pool.pool_creator_id_fkey
CreatorNoteAudios NoteAudioSlice // note_audio.note_audio_creator_id_fkey
DeletorNoteAudios NoteAudioSlice // note_audio.note_audio_deletor_id_fkey
CreatorNoteImages NoteImageSlice // note_image.note_image_creator_id_fkey
DeletorNoteImages NoteImageSlice // note_image.note_image_deletor_id_fkey
UserNotifications NotificationSlice // notification.notification_user_id_fkey
CreatorPools PoolSlice // pool.pool_creator_id_fkey
CreatorResidents ResidentSlice // resident.resident_creator_fkey
CreatorSites SiteSlice // site.site_creator_id_fkey
Organization *Organization // user_.user__organization_id_fkey
UserOauthTokens ArcgisOauthTokenSlice // arcgis.oauth_token.oauth_token_user_id_fkey
PublicUserUser ArcgisUserSlice // arcgis.user_.user__public_user_id_fkey
CreatorComplianceReportRequests ComplianceReportRequestSlice // compliance_report_request.compliance_report_request_creator_fkey
CreatorFiles FileuploadFileSlice // fileupload.file.file_creator_id_fkey
CreatorFlyoverAerialServices FileuploadFlyoverAerialServiceSlice // fileupload.flyover_aerial_service.flyover_aerial_service_creator_id_fkey
FileuploadPool FileuploadPoolSlice // fileupload.pool.pool_creator_id_fkey
CreatorNoteAudios NoteAudioSlice // note_audio.note_audio_creator_id_fkey
DeletorNoteAudios NoteAudioSlice // note_audio.note_audio_deletor_id_fkey
CreatorNoteImages NoteImageSlice // note_image.note_image_creator_id_fkey
DeletorNoteImages NoteImageSlice // note_image.note_image_deletor_id_fkey
UserNotifications NotificationSlice // notification.notification_user_id_fkey
CreatorPools PoolSlice // pool.pool_creator_id_fkey
CreatorResidents ResidentSlice // resident.resident_creator_fkey
CreatorSites SiteSlice // site.site_creator_id_fkey
Organization *Organization // user_.user__organization_id_fkey
}
func buildUserColumns(alias string) userColumns {
@ -736,6 +737,30 @@ func (os UserSlice) CreatorFiles(mods ...bob.Mod[*dialect.SelectQuery]) Fileuplo
)...)
}
// CreatorFlyoverAerialServices starts a query for related objects on fileupload.flyover_aerial_service
func (o *User) CreatorFlyoverAerialServices(mods ...bob.Mod[*dialect.SelectQuery]) FileuploadFlyoverAerialServicesQuery {
return FileuploadFlyoverAerialServices.Query(append(mods,
sm.Where(FileuploadFlyoverAerialServices.Columns.CreatorID.EQ(psql.Arg(o.ID))),
)...)
}
func (os UserSlice) CreatorFlyoverAerialServices(mods ...bob.Mod[*dialect.SelectQuery]) FileuploadFlyoverAerialServicesQuery {
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 FileuploadFlyoverAerialServices.Query(append(mods,
sm.Where(psql.Group(FileuploadFlyoverAerialServices.Columns.CreatorID).OP("IN", PKArgExpr)),
)...)
}
// FileuploadPool starts a query for related objects on fileupload.pool
func (o *User) FileuploadPool(mods ...bob.Mod[*dialect.SelectQuery]) FileuploadPoolsQuery {
return FileuploadPools.Query(append(mods,
@ -1248,6 +1273,74 @@ func (user0 *User) AttachCreatorFiles(ctx context.Context, exec bob.Executor, re
return nil
}
func insertUserCreatorFlyoverAerialServices0(ctx context.Context, exec bob.Executor, fileuploadFlyoverAerialServices1 []*FileuploadFlyoverAerialServiceSetter, user0 *User) (FileuploadFlyoverAerialServiceSlice, error) {
for i := range fileuploadFlyoverAerialServices1 {
fileuploadFlyoverAerialServices1[i].CreatorID = omit.From(user0.ID)
}
ret, err := FileuploadFlyoverAerialServices.Insert(bob.ToMods(fileuploadFlyoverAerialServices1...)).All(ctx, exec)
if err != nil {
return ret, fmt.Errorf("insertUserCreatorFlyoverAerialServices0: %w", err)
}
return ret, nil
}
func attachUserCreatorFlyoverAerialServices0(ctx context.Context, exec bob.Executor, count int, fileuploadFlyoverAerialServices1 FileuploadFlyoverAerialServiceSlice, user0 *User) (FileuploadFlyoverAerialServiceSlice, error) {
setter := &FileuploadFlyoverAerialServiceSetter{
CreatorID: omit.From(user0.ID),
}
err := fileuploadFlyoverAerialServices1.UpdateAll(ctx, exec, *setter)
if err != nil {
return nil, fmt.Errorf("attachUserCreatorFlyoverAerialServices0: %w", err)
}
return fileuploadFlyoverAerialServices1, nil
}
func (user0 *User) InsertCreatorFlyoverAerialServices(ctx context.Context, exec bob.Executor, related ...*FileuploadFlyoverAerialServiceSetter) error {
if len(related) == 0 {
return nil
}
var err error
fileuploadFlyoverAerialServices1, err := insertUserCreatorFlyoverAerialServices0(ctx, exec, related, user0)
if err != nil {
return err
}
user0.R.CreatorFlyoverAerialServices = append(user0.R.CreatorFlyoverAerialServices, fileuploadFlyoverAerialServices1...)
for _, rel := range fileuploadFlyoverAerialServices1 {
rel.R.CreatorUser = user0
}
return nil
}
func (user0 *User) AttachCreatorFlyoverAerialServices(ctx context.Context, exec bob.Executor, related ...*FileuploadFlyoverAerialService) error {
if len(related) == 0 {
return nil
}
var err error
fileuploadFlyoverAerialServices1 := FileuploadFlyoverAerialServiceSlice(related)
_, err = attachUserCreatorFlyoverAerialServices0(ctx, exec, len(related), fileuploadFlyoverAerialServices1, user0)
if err != nil {
return err
}
user0.R.CreatorFlyoverAerialServices = append(user0.R.CreatorFlyoverAerialServices, fileuploadFlyoverAerialServices1...)
for _, rel := range related {
rel.R.CreatorUser = user0
}
return nil
}
func insertUserFileuploadPool0(ctx context.Context, exec bob.Executor, fileuploadPools1 []*FileuploadPoolSetter, user0 *User) (FileuploadPoolSlice, error) {
for i := range fileuploadPools1 {
fileuploadPools1[i].CreatorID = omit.From(user0.ID)
@ -2002,6 +2095,20 @@ func (o *User) Preload(name string, retrieved any) error {
o.R.CreatorFiles = rels
for _, rel := range rels {
if rel != nil {
rel.R.CreatorUser = o
}
}
return nil
case "CreatorFlyoverAerialServices":
rels, ok := retrieved.(FileuploadFlyoverAerialServiceSlice)
if !ok {
return fmt.Errorf("user cannot load %T as %q", retrieved, name)
}
o.R.CreatorFlyoverAerialServices = rels
for _, rel := range rels {
if rel != nil {
rel.R.CreatorUser = o
@ -2178,6 +2285,7 @@ type userThenLoader[Q orm.Loadable] struct {
PublicUserUser func(...bob.Mod[*dialect.SelectQuery]) orm.Loader[Q]
CreatorComplianceReportRequests func(...bob.Mod[*dialect.SelectQuery]) orm.Loader[Q]
CreatorFiles func(...bob.Mod[*dialect.SelectQuery]) orm.Loader[Q]
CreatorFlyoverAerialServices func(...bob.Mod[*dialect.SelectQuery]) orm.Loader[Q]
FileuploadPool func(...bob.Mod[*dialect.SelectQuery]) orm.Loader[Q]
CreatorNoteAudios func(...bob.Mod[*dialect.SelectQuery]) orm.Loader[Q]
DeletorNoteAudios func(...bob.Mod[*dialect.SelectQuery]) orm.Loader[Q]
@ -2203,6 +2311,9 @@ func buildUserThenLoader[Q orm.Loadable]() userThenLoader[Q] {
type CreatorFilesLoadInterface interface {
LoadCreatorFiles(context.Context, bob.Executor, ...bob.Mod[*dialect.SelectQuery]) error
}
type CreatorFlyoverAerialServicesLoadInterface interface {
LoadCreatorFlyoverAerialServices(context.Context, bob.Executor, ...bob.Mod[*dialect.SelectQuery]) error
}
type FileuploadPoolLoadInterface interface {
LoadFileuploadPool(context.Context, bob.Executor, ...bob.Mod[*dialect.SelectQuery]) error
}
@ -2259,6 +2370,12 @@ func buildUserThenLoader[Q orm.Loadable]() userThenLoader[Q] {
return retrieved.LoadCreatorFiles(ctx, exec, mods...)
},
),
CreatorFlyoverAerialServices: thenLoadBuilder[Q](
"CreatorFlyoverAerialServices",
func(ctx context.Context, exec bob.Executor, retrieved CreatorFlyoverAerialServicesLoadInterface, mods ...bob.Mod[*dialect.SelectQuery]) error {
return retrieved.LoadCreatorFlyoverAerialServices(ctx, exec, mods...)
},
),
FileuploadPool: thenLoadBuilder[Q](
"FileuploadPool",
func(ctx context.Context, exec bob.Executor, retrieved FileuploadPoolLoadInterface, mods ...bob.Mod[*dialect.SelectQuery]) error {
@ -2566,6 +2683,67 @@ func (os UserSlice) LoadCreatorFiles(ctx context.Context, exec bob.Executor, mod
return nil
}
// LoadCreatorFlyoverAerialServices loads the user's CreatorFlyoverAerialServices into the .R struct
func (o *User) LoadCreatorFlyoverAerialServices(ctx context.Context, exec bob.Executor, mods ...bob.Mod[*dialect.SelectQuery]) error {
if o == nil {
return nil
}
// Reset the relationship
o.R.CreatorFlyoverAerialServices = nil
related, err := o.CreatorFlyoverAerialServices(mods...).All(ctx, exec)
if err != nil {
return err
}
for _, rel := range related {
rel.R.CreatorUser = o
}
o.R.CreatorFlyoverAerialServices = related
return nil
}
// LoadCreatorFlyoverAerialServices loads the user's CreatorFlyoverAerialServices into the .R struct
func (os UserSlice) LoadCreatorFlyoverAerialServices(ctx context.Context, exec bob.Executor, mods ...bob.Mod[*dialect.SelectQuery]) error {
if len(os) == 0 {
return nil
}
fileuploadFlyoverAerialServices, err := os.CreatorFlyoverAerialServices(mods...).All(ctx, exec)
if err != nil {
return err
}
for _, o := range os {
if o == nil {
continue
}
o.R.CreatorFlyoverAerialServices = nil
}
for _, o := range os {
if o == nil {
continue
}
for _, rel := range fileuploadFlyoverAerialServices {
if !(o.ID == rel.CreatorID) {
continue
}
rel.R.CreatorUser = o
o.R.CreatorFlyoverAerialServices = append(o.R.CreatorFlyoverAerialServices, rel)
}
}
return nil
}
// LoadFileuploadPool loads the user's FileuploadPool into the .R struct
func (o *User) LoadFileuploadPool(ctx context.Context, exec bob.Executor, mods ...bob.Mod[*dialect.SelectQuery]) error {
if o == nil {
@ -3179,6 +3357,7 @@ type userC struct {
PublicUserUser *int64
CreatorComplianceReportRequests *int64
CreatorFiles *int64
CreatorFlyoverAerialServices *int64
FileuploadPool *int64
CreatorNoteAudios *int64
DeletorNoteAudios *int64
@ -3205,6 +3384,8 @@ func (o *User) PreloadCount(name string, count int64) error {
o.C.CreatorComplianceReportRequests = &count
case "CreatorFiles":
o.C.CreatorFiles = &count
case "CreatorFlyoverAerialServices":
o.C.CreatorFlyoverAerialServices = &count
case "FileuploadPool":
o.C.FileuploadPool = &count
case "CreatorNoteAudios":
@ -3232,6 +3413,7 @@ type userCountPreloader struct {
PublicUserUser func(...bob.Mod[*dialect.SelectQuery]) psql.Preloader
CreatorComplianceReportRequests func(...bob.Mod[*dialect.SelectQuery]) psql.Preloader
CreatorFiles func(...bob.Mod[*dialect.SelectQuery]) psql.Preloader
CreatorFlyoverAerialServices func(...bob.Mod[*dialect.SelectQuery]) psql.Preloader
FileuploadPool func(...bob.Mod[*dialect.SelectQuery]) psql.Preloader
CreatorNoteAudios func(...bob.Mod[*dialect.SelectQuery]) psql.Preloader
DeletorNoteAudios func(...bob.Mod[*dialect.SelectQuery]) psql.Preloader
@ -3313,6 +3495,23 @@ func buildUserCountPreloader() userCountPreloader {
return psql.Group(psql.Select(subqueryMods...).Expression)
})
},
CreatorFlyoverAerialServices: func(mods ...bob.Mod[*dialect.SelectQuery]) psql.Preloader {
return countPreloader[*User]("CreatorFlyoverAerialServices", func(parent string) bob.Expression {
// Build a correlated subquery: (SELECT COUNT(*) FROM related WHERE fk = parent.pk)
if parent == "" {
parent = Users.Alias()
}
subqueryMods := []bob.Mod[*dialect.SelectQuery]{
sm.Columns(psql.Raw("count(*)")),
sm.From(FileuploadFlyoverAerialServices.Name()),
sm.Where(psql.Quote(FileuploadFlyoverAerialServices.Alias(), "creator_id").EQ(psql.Quote(parent, "id"))),
}
subqueryMods = append(subqueryMods, mods...)
return psql.Group(psql.Select(subqueryMods...).Expression)
})
},
FileuploadPool: func(mods ...bob.Mod[*dialect.SelectQuery]) psql.Preloader {
return countPreloader[*User]("FileuploadPool", func(parent string) bob.Expression {
// Build a correlated subquery: (SELECT COUNT(*) FROM related WHERE fk = parent.pk)
@ -3474,6 +3673,7 @@ type userCountThenLoader[Q orm.Loadable] struct {
PublicUserUser func(...bob.Mod[*dialect.SelectQuery]) orm.Loader[Q]
CreatorComplianceReportRequests func(...bob.Mod[*dialect.SelectQuery]) orm.Loader[Q]
CreatorFiles func(...bob.Mod[*dialect.SelectQuery]) orm.Loader[Q]
CreatorFlyoverAerialServices func(...bob.Mod[*dialect.SelectQuery]) orm.Loader[Q]
FileuploadPool func(...bob.Mod[*dialect.SelectQuery]) orm.Loader[Q]
CreatorNoteAudios func(...bob.Mod[*dialect.SelectQuery]) orm.Loader[Q]
DeletorNoteAudios func(...bob.Mod[*dialect.SelectQuery]) orm.Loader[Q]
@ -3498,6 +3698,9 @@ func buildUserCountThenLoader[Q orm.Loadable]() userCountThenLoader[Q] {
type CreatorFilesCountInterface interface {
LoadCountCreatorFiles(context.Context, bob.Executor, ...bob.Mod[*dialect.SelectQuery]) error
}
type CreatorFlyoverAerialServicesCountInterface interface {
LoadCountCreatorFlyoverAerialServices(context.Context, bob.Executor, ...bob.Mod[*dialect.SelectQuery]) error
}
type FileuploadPoolCountInterface interface {
LoadCountFileuploadPool(context.Context, bob.Executor, ...bob.Mod[*dialect.SelectQuery]) error
}
@ -3551,6 +3754,12 @@ func buildUserCountThenLoader[Q orm.Loadable]() userCountThenLoader[Q] {
return retrieved.LoadCountCreatorFiles(ctx, exec, mods...)
},
),
CreatorFlyoverAerialServices: countThenLoadBuilder[Q](
"CreatorFlyoverAerialServices",
func(ctx context.Context, exec bob.Executor, retrieved CreatorFlyoverAerialServicesCountInterface, mods ...bob.Mod[*dialect.SelectQuery]) error {
return retrieved.LoadCountCreatorFlyoverAerialServices(ctx, exec, mods...)
},
),
FileuploadPool: countThenLoadBuilder[Q](
"FileuploadPool",
func(ctx context.Context, exec bob.Executor, retrieved FileuploadPoolCountInterface, mods ...bob.Mod[*dialect.SelectQuery]) error {
@ -3728,6 +3937,36 @@ func (os UserSlice) LoadCountCreatorFiles(ctx context.Context, exec bob.Executor
return nil
}
// LoadCountCreatorFlyoverAerialServices loads the count of CreatorFlyoverAerialServices into the C struct
func (o *User) LoadCountCreatorFlyoverAerialServices(ctx context.Context, exec bob.Executor, mods ...bob.Mod[*dialect.SelectQuery]) error {
if o == nil {
return nil
}
count, err := o.CreatorFlyoverAerialServices(mods...).Count(ctx, exec)
if err != nil {
return err
}
o.C.CreatorFlyoverAerialServices = &count
return nil
}
// LoadCountCreatorFlyoverAerialServices loads the count of CreatorFlyoverAerialServices for a slice
func (os UserSlice) LoadCountCreatorFlyoverAerialServices(ctx context.Context, exec bob.Executor, mods ...bob.Mod[*dialect.SelectQuery]) error {
if len(os) == 0 {
return nil
}
for _, o := range os {
if err := o.LoadCountCreatorFlyoverAerialServices(ctx, exec, mods...); err != nil {
return err
}
}
return nil
}
// LoadCountFileuploadPool loads the count of FileuploadPool into the C struct
func (o *User) LoadCountFileuploadPool(ctx context.Context, exec bob.Executor, mods ...bob.Mod[*dialect.SelectQuery]) error {
if o == nil {
@ -4004,6 +4243,7 @@ type userJoins[Q dialect.Joinable] struct {
PublicUserUser modAs[Q, arcgisuserColumns]
CreatorComplianceReportRequests modAs[Q, complianceReportRequestColumns]
CreatorFiles modAs[Q, fileuploadFileColumns]
CreatorFlyoverAerialServices modAs[Q, fileuploadFlyoverAerialServiceColumns]
FileuploadPool modAs[Q, fileuploadPoolColumns]
CreatorNoteAudios modAs[Q, noteAudioColumns]
DeletorNoteAudios modAs[Q, noteAudioColumns]
@ -4079,6 +4319,20 @@ func buildUserJoins[Q dialect.Joinable](cols userColumns, typ string) userJoins[
return mods
},
},
CreatorFlyoverAerialServices: modAs[Q, fileuploadFlyoverAerialServiceColumns]{
c: FileuploadFlyoverAerialServices.Columns,
f: func(to fileuploadFlyoverAerialServiceColumns) bob.Mod[Q] {
mods := make(mods.QueryMods[Q], 0, 1)
{
mods = append(mods, dialect.Join[Q](typ, FileuploadFlyoverAerialServices.Name().As(to.Alias())).On(
to.CreatorID.EQ(cols.ID),
))
}
return mods
},
},
FileuploadPool: modAs[Q, fileuploadPoolColumns]{
c: FileuploadPools.Columns,
f: func(to fileuploadPoolColumns) bob.Mod[Q] {

View file

@ -79,6 +79,8 @@ func displayUploadType(s string) string {
switch s {
case "PoolList":
return "Green Pool List"
case "Flyover":
return "Flyover"
default:
return "Unknown upload type"
}

View file

@ -204,12 +204,14 @@ document.addEventListener('DOMContentLoaded', onLoad);
</div>
<div class="d-flex justify-content-between mt-4 mb-5">
<form action="{{ .C.URL.Discard }}" method="POST">
<form action="{{ call .URL.Upload.Discard .C.CSVFileID }}" method="POST">
<button type="submit" class="btn btn-outline-danger">Discard</button>
</form>
<button class="btn btn-primary" id="confirmUploadBtn">
<i class="bi bi-check2 me-1"></i> Confirm and Submit Data
</button>
<form action="{{ call .URL.Upload.Commit .C.CSVFileID }}" method="POST">
<button class="btn btn-primary" id="confirmUploadBtn">
<i class="bi bi-check2 me-1"></i> Confirm and Submit Data
</button>
</form>
</div>
</div>
{{ end }}

View file

@ -57,7 +57,7 @@
</div>
<div class="card-body">
<form
action="{{ .URL.Upload.PoolBob }}"
action="{{ .URL.Upload.PoolFlyover }}"
method="POST"
enctype="multipart/form-data"
>

View file

@ -56,7 +56,7 @@
</div>
<a
class="btn btn-primary btn-lg w-100"
href="{{ .URL.Upload.PoolBob }}"
href="{{ .URL.Upload.PoolFlyover }}"
>
<i class="bi bi-upload me-2"></i>Let's do this
</a>

View file

@ -116,7 +116,7 @@
<td>
<a
class="btn btn-sm btn-outline-primary"
href="/upload/{{ .ID }}"
href="/configuration/upload/{{ .ID }}"
>View</a
>
</td>

128
platform/csv/csv.go Normal file
View file

@ -0,0 +1,128 @@
package csv
import (
"context"
//"encoding/csv"
"fmt"
//"io"
"strconv"
"strings"
//"sync"
//"time"
"github.com/Gleipnir-Technology/bob"
"github.com/Gleipnir-Technology/bob/dialect/psql"
"github.com/Gleipnir-Technology/bob/dialect/psql/um"
//"github.com/Gleipnir-Technology/nidus-sync/config"
"github.com/Gleipnir-Technology/nidus-sync/db"
"github.com/Gleipnir-Technology/nidus-sync/db/enums"
"github.com/Gleipnir-Technology/nidus-sync/db/models"
//"github.com/Gleipnir-Technology/nidus-sync/h3utils"
//"github.com/Gleipnir-Technology/nidus-sync/platform/geom"
//"github.com/Gleipnir-Technology/nidus-sync/platform/text"
//"github.com/Gleipnir-Technology/nidus-sync/stadia"
//"github.com/Gleipnir-Technology/nidus-sync/userfile"
"github.com/aarondl/opt/omit"
//"github.com/aarondl/opt/omitnull"
"github.com/rs/zerolog/log"
)
type csvParserFunc[T any] = func(context.Context, bob.Tx, *models.FileuploadFile, *models.FileuploadCSV) ([]T, error)
type csvProcessorFunc[T any] = func(context.Context, bob.Tx, *models.FileuploadFile, *models.FileuploadCSV, []T) error
func ProcessJob(ctx context.Context, file_id int32, type_ enums.FileuploadCsvtype) error {
var err error
switch type_ {
case enums.FileuploadCsvtypePoollist:
err = processCSV(ctx, file_id, parseCSVPoollist, processCSVPoollist)
case enums.FileuploadCsvtypeFlyover:
err = processCSV(ctx, file_id, parseCSVFlyover, processCSVFlyover)
}
return err
}
func processCSV[T any](ctx context.Context, file_id int32, parser csvParserFunc[T], processor csvProcessorFunc[T]) error {
file, c, err := loadFileAndCSV(ctx, file_id)
if err != nil {
return fmt.Errorf("load file and csv: %w", err)
}
txn, err := db.PGInstance.BobDB.BeginTx(ctx, nil)
if err != nil {
return fmt.Errorf("Failed to start transaction: %w", err)
}
defer txn.Rollback(ctx)
parsed, err := parser(ctx, txn, file, c)
if err != nil {
return fmt.Errorf("parse file: %w", err)
}
_, err = psql.Update(
um.Table("fileupload.csv"),
um.SetCol("rowcount").ToArg(len(parsed)),
um.Where(psql.Quote("file_id").EQ(psql.Arg(file_id))),
).Exec(ctx, txn)
if err != nil {
return fmt.Errorf("update csv row: %w", err)
}
err = processor(ctx, txn, file, c, parsed)
if err != nil {
return fmt.Errorf("process parsed file: %w", err)
}
file.Update(ctx, txn, &models.FileuploadFileSetter{
Status: omit.From(enums.FileuploadFilestatustypeParsed),
})
log.Info().Int32("file.ID", file.ID).Msg("Set file to parsed")
txn.Commit(ctx)
return nil
}
func loadFileAndCSV(ctx context.Context, file_id int32) (*models.FileuploadFile, *models.FileuploadCSV, error) {
file, err := models.FindFileuploadFile(ctx, db.PGInstance.BobDB, file_id)
if err != nil {
return nil, nil, fmt.Errorf("Failed to get file %d from DB: %w", file_id, err)
}
c, err := models.FindFileuploadCSV(ctx, db.PGInstance.BobDB, file.ID)
if err != nil {
return nil, nil, fmt.Errorf("Failed to get csv file %d from DB: %w", file.ID, err)
}
return file, c, nil
}
func addError(ctx context.Context, txn bob.Tx, c *models.FileuploadCSV, row_number int32, column_number int32, msg string) error {
r, err := models.FileuploadErrorCSVS.Insert(&models.FileuploadErrorCSVSetter{
Col: omit.From(column_number),
CSVFileID: omit.From(c.FileID),
// ID
Line: omit.From(row_number),
Message: omit.From(msg),
}).One(ctx, txn)
if err != nil {
return fmt.Errorf("Failed to add error: %w", err)
}
log.Info().Int32("id", r.ID).Int32("file_id", c.FileID).Str("msg", msg).Int32("row", row_number).Int32("col", column_number).Msg("Created CSV file error")
return nil
}
func addImportError(file *models.FileuploadFile, err error) {
log.Debug().Err(err).Int32("file_id", file.ID).Msg("Fake add import error")
}
func parseBool(s string) (bool, error) {
sl := strings.ToLower(s)
boolValue, err := strconv.ParseBool(sl)
if err != nil {
// Handle some of the stuff that strconv doesn't handle
switch sl {
case "yes":
return true, nil
case "no":
return false, nil
default:
return false, fmt.Errorf("unrecognized '%s'", sl)
}
}
return boolValue, err
}
func errorMissingHeader(ctx context.Context, txn bob.Tx, c *models.FileuploadCSV, h headerPoolEnum) error {
msg := fmt.Sprintf("The file is missing the '%s' header", h.String())
return addError(ctx, txn, c, 0, 0, msg)
}

307
platform/csv/flyover.go Normal file
View file

@ -0,0 +1,307 @@
package csv
import (
"context"
"encoding/csv"
"fmt"
"io"
"strconv"
"strings"
"time"
"github.com/Gleipnir-Technology/bob"
"github.com/Gleipnir-Technology/bob/dialect/psql"
"github.com/Gleipnir-Technology/bob/dialect/psql/um"
"github.com/Gleipnir-Technology/nidus-sync/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/platform/geom"
"github.com/Gleipnir-Technology/nidus-sync/platform/text"
"github.com/Gleipnir-Technology/nidus-sync/userfile"
"github.com/aarondl/opt/omit"
"github.com/aarondl/opt/omitnull"
"github.com/rs/zerolog/log"
)
type Enum interface {
~int | ~int8 | ~int16 | ~int32 | ~int64 | ~string
}
type headerFlyoverEnum int
const (
headerFlyoverComment headerFlyoverEnum = iota
headerFlyoverLatitude
headerFlyoverLongitude
headerFlyoverNone
)
func (e headerFlyoverEnum) String() string {
switch e {
case headerFlyoverComment:
return "Comment"
case headerFlyoverLatitude:
return "TargetLat"
case headerFlyoverLongitude:
return "TargetLon"
default:
return "bad programmer"
}
}
var parseCSVFlyover = makeParseCSV(
makeParseHeaders(map[string]headerFlyoverEnum{
"comment": headerFlyoverComment,
"targetlat": headerFlyoverLatitude,
"targetlon": headerFlyoverLongitude,
"*": headerFlyoverNone,
}),
insertFlyover,
)
type insertModelFunc[ModelType any, HeaderType Enum] = func(context.Context, bob.Tx, *models.FileuploadFile, *models.FileuploadCSV, int32, []HeaderType, []string, []string) (ModelType, error)
type parseCSVFunc[ModelType any] = func(ctx context.Context, txn bob.Tx, file *models.FileuploadFile, c *models.FileuploadCSV) ([]ModelType, error)
func makeParseCSV[ModelType any, HeaderType Enum](parseHeader parseHeaderFunc[HeaderType], insertModel insertModelFunc[ModelType, HeaderType]) parseCSVFunc[ModelType] {
return func(ctx context.Context, txn bob.Tx, file *models.FileuploadFile, c *models.FileuploadCSV) ([]ModelType, error) {
rows := make([]ModelType, 0)
r, err := userfile.NewFileReader(userfile.CollectionCSV, file.FileUUID)
if err != nil {
return rows, fmt.Errorf("Failed to get filereader for %d: %w", file.ID, err)
}
reader := csv.NewReader(r)
h, err := reader.Read()
if err != nil {
return rows, fmt.Errorf("Failed to read header of CSV for file %d: %w", file.ID, err)
}
header_types, header_names := parseHeader(h)
/*
TODO: Add support for missing headersi
missing_headers := missingRequiredHeaders(header_types)
for _, mh := range missing_headers {
errorMissingHeader(ctx, txn, c, mh)
file.Update(ctx, txn, &models.FileuploadFileSetter{
Status: omit.From(enums.FileuploadFilestatustypeError),
})
return pools, nil
}
*/
// Start at 2 because the header is line 1, not line 0
line_number := int32(2)
for {
row, err := reader.Read()
if err != nil {
if err == io.EOF {
return rows, nil
}
return rows, fmt.Errorf("Failed to read all CSV records for file %d: %w", file.ID, err)
}
m, err := insertModel(ctx, txn, file, c, line_number, header_types, header_names, row)
rows = append(rows, m)
line_number = line_number + 1
}
}
}
func insertFlyover(ctx context.Context, txn bob.Tx, file *models.FileuploadFile, c *models.FileuploadCSV, line_number int32, header_types []headerFlyoverEnum, header_names []string, row []string) (*models.FileuploadFlyoverAerialService, error) {
setter := models.FileuploadFlyoverAerialServiceSetter{
Committed: omit.From(false),
Condition: omit.From(enums.FileuploadPoolconditiontypeUnknown),
Created: omit.From(time.Now()),
CreatorID: omit.From(file.CreatorID),
CSVFile: omit.From(file.ID),
Deleted: omitnull.FromPtr[time.Time](nil),
Geom: omitnull.FromPtr[string](nil),
H3cell: omitnull.FromPtr[string](nil),
// ID - generated
OrganizationID: omit.From(file.OrganizationID),
}
var lat, lng float64
var err error
for i, value := range row {
if value == "" {
continue
}
header_type := header_types[i]
switch header_type {
case headerFlyoverComment:
condition, err := parsePoolCondition(value)
if err == nil {
setter.Condition = omit.From(condition)
} else {
addError(ctx, txn, c, int32(line_number), int32(i), fmt.Sprintf("'%s' is not a pool condition that we recognize. It should be one of %s", value, poolConditionValidValues()))
continue
}
case headerFlyoverLatitude:
lat, err = strconv.ParseFloat(value, 10)
if err != nil {
addError(ctx, txn, c, int32(line_number), int32(i), fmt.Sprintf("'%s' is not decimal value", value))
continue
}
case headerFlyoverLongitude:
lng, err = strconv.ParseFloat(value, 10)
if err != nil {
addError(ctx, txn, c, int32(line_number), int32(i), fmt.Sprintf("'%s' is not decimal value", value))
continue
}
}
}
flyover, err := models.FileuploadFlyoverAerialServices.Insert(&setter).One(ctx, txn)
if err != nil {
return nil, fmt.Errorf("Failed to create flyover: %w", err)
}
cell, err := h3utils.GetCell(lng, lat, 15)
if err != nil {
return nil, fmt.Errorf("failed to convert lat %f lng %f to h3 cell", lng, lat)
}
geom_query := geom.PostgisPointQuery(lng, lat)
_, err = psql.Update(
um.Table("fileupload.flyover_aerial_service"),
um.SetCol("h3cell").ToArg(cell),
um.SetCol("geom").To(geom_query),
um.Where(psql.Quote("id").EQ(psql.Arg(flyover.ID))),
).Exec(ctx, txn)
if err != nil {
return nil, fmt.Errorf("failed to update flyover geometry: %w", err)
}
return flyover, nil
}
func insertPoollistRow(ctx context.Context, txn bob.Tx, file *models.FileuploadFile, c *models.FileuploadCSV, line_number int32, header_types []headerPoolEnum, header_names []string, row []string) (*models.FileuploadPool, error) {
tags := make(map[string]string, 0)
// Start with a setter with default values, comment out the required fields to ensure they're set
setter := models.FileuploadPoolSetter{
// AddressCity: omit.From(),
// AddressPostalCode: omit.From(),
// AddressStreet: omit.From(),
Committed: omit.From(false),
Condition: omit.From(enums.FileuploadPoolconditiontypeUnknown),
Created: omit.From(time.Now()),
CreatorID: omit.From(file.CreatorID),
CSVFile: omit.From(file.ID),
Deleted: omitnull.FromPtr[time.Time](nil),
Geom: omitnull.FromPtr[string](nil),
H3cell: omitnull.FromPtr[string](nil),
// ID - generated
IsInDistrict: omit.From(false),
IsNew: omit.From(true),
LineNumber: omit.From(line_number),
Notes: omit.From(""),
OrganizationID: omit.From(file.OrganizationID),
PropertyOwnerName: omit.From(""),
PropertyOwnerPhoneE164: omitnull.FromPtr[string](nil),
ResidentOwned: omitnull.FromPtr[bool](nil),
ResidentPhoneE164: omitnull.FromPtr[string](nil),
// Can't set this via a Setter
// Tags: convertToPGData(tags),
}
for i, value := range row {
if value == "" {
continue
}
header_type := header_types[i]
switch header_type {
case headerAddressCity:
setter.AddressCity = omit.From(value)
case headerAddressPostalCode:
setter.AddressPostalCode = omit.From(value)
case headerAddressStreet:
setter.AddressStreet = omit.From(value)
case headerCondition:
condition, err := parsePoolCondition(value)
if err == nil {
setter.Condition = omit.From(condition)
} else {
addError(ctx, txn, c, int32(line_number), int32(i), fmt.Sprintf("'%s' is not a pool condition that we recognize. It should be one of %s", value, poolConditionValidValues()))
continue
}
case headerNotes:
setter.Notes = omit.From(value)
case headerPropertyOwnerName:
setter.PropertyOwnerName = omit.From(value)
case headerPropertyOwnerPhone:
phone, err := text.ParsePhoneNumber(value)
if err != nil {
addError(ctx, txn, c, int32(line_number), int32(i), fmt.Sprintf("'%s' is not a phone number that we recognize. Ideally it should be of the form '+12223334444'", value))
continue
}
text.EnsureInDB(ctx, txn, *phone)
setter.PropertyOwnerPhoneE164 = omitnull.From(text.PhoneString(*phone))
case headerResidentOwned:
boolValue, err := parseBool(value)
if err != nil {
addError(ctx, txn, c, int32(line_number), int32(i), fmt.Sprintf("'%s' is not something that we recognize as a true/false value. Please use either 'true' or 'false'", value))
continue
}
setter.ResidentOwned = omitnull.From(boolValue)
case headerResidentPhone:
phone, err := text.ParsePhoneNumber(value)
if err != nil {
addError(ctx, txn, c, int32(line_number), int32(i), fmt.Sprintf("'%s' is not a phone number that we recognize. Ideally it should be of the form '+12223334444'", value))
continue
}
text.EnsureInDB(ctx, txn, *phone)
setter.ResidentPhoneE164 = omitnull.From(text.PhoneString(*phone))
case headerTag:
tags[header_names[i]] = value
}
}
setter.Tags = omit.From(db.ConvertToPGData(tags))
return models.FileuploadPools.Insert(&setter).One(ctx, txn)
}
type parseHeaderFunc[EnumType any] = func(row []string) ([]EnumType, []string)
func makeParseHeaders[EnumType any](headerToType map[string]EnumType) parseHeaderFunc[EnumType] {
return func(row []string) ([]EnumType, []string) {
result_enums := make([]EnumType, len(row))
result_names := make([]string, len(row))
for i, h := range row {
ht := strings.TrimSpace(h)
hl := strings.ToLower(ht)
log.Debug().Str("header", hl).Msg("Saw CSV header")
var type_ EnumType
type_, ok := headerToType[hl]
if !ok {
// See if there is a '*' entry which should match anything
all_type, ok2 := headerToType["*"]
if !ok2 {
log.Error().Str("name", hl).Msg("No header type matches column. You should add a '*' to the makeParseHeaders call")
continue
} else {
type_ = all_type
}
}
result_enums[i] = type_
result_names[i] = hl
}
return result_enums, result_names
}
}
func processCSVFlyover(ctx context.Context, txn bob.Tx, file *models.FileuploadFile, c *models.FileuploadCSV, rows []*models.FileuploadFlyoverAerialService) error {
return nil
}
var poolConditionAliases = map[string]string{
"covered": "unknown",
"dark bottom": "unknown",
"no data": "unknown",
"empty": "dry",
"green": "green",
"murky pool": "murky",
"putting green": "false pool",
"questionable": "unknown",
}
func parsePoolCondition(c string) (enums.FileuploadPoolconditiontype, error) {
var condition enums.FileuploadPoolconditiontype
col_l := strings.ToLower(c)
col_translated, ok := poolConditionAliases[col_l]
if ok {
col_l = col_translated
}
err := condition.Scan(col_l)
return condition, err
}

View file

@ -5,7 +5,6 @@ import (
"encoding/csv"
"fmt"
"io"
"strconv"
"strings"
"sync"
"time"
@ -66,47 +65,6 @@ func (e headerPoolEnum) String() string {
return "bad programmer"
}
}
func ProcessJob(ctx context.Context, file_id int32) error {
file, err := models.FindFileuploadFile(ctx, db.PGInstance.BobDB, file_id)
if err != nil {
return fmt.Errorf("Failed to get file %d from DB: %w", file_id, err)
}
txn, err := db.PGInstance.BobDB.BeginTx(ctx, nil)
if err != nil {
return fmt.Errorf("Failed to start transaction: %w", err)
}
defer txn.Rollback(ctx)
c, err := models.FindFileuploadCSV(ctx, txn, file.ID)
if err != nil {
return fmt.Errorf("Failed to get csv file %d from DB: %w", file.ID, err)
}
pools, err := parseFile(ctx, txn, file, c)
if err != nil {
return fmt.Errorf("parse file: %w", err)
}
_, err = psql.Update(
um.Table("fileupload.csv"),
um.SetCol("rowcount").ToArg(len(pools)),
um.Where(psql.Quote("file_id").EQ(psql.Arg(file_id))),
).Exec(ctx, txn)
if err != nil {
return fmt.Errorf("update csv row: %w", err)
}
org, err := models.FindOrganization(ctx, db.PGInstance.BobDB, file.OrganizationID)
if err != nil {
return fmt.Errorf("get org: %w", err)
}
err = bulkGeocode(ctx, txn, file, c, pools, org)
if err != nil {
log.Error().Err(err).Msg("Failure during geocoding")
}
file.Update(ctx, txn, &models.FileuploadFileSetter{
Status: omit.From(enums.FileuploadFilestatustypeParsed),
})
log.Info().Int32("file.ID", file.ID).Msg("Set file to parsed")
txn.Commit(ctx)
return nil
}
func bulkGeocode(ctx context.Context, txn bob.Tx, file *models.FileuploadFile, c *models.FileuploadCSV, pools []*models.FileuploadPool, org *models.Organization) error {
if len(pools) == 0 {
return nil
@ -215,7 +173,7 @@ func geocode(ctx context.Context, txn bob.Tx, client *stadia.StadiaMaps, job *jo
}
return nil
}
func parseFile(ctx context.Context, txn bob.Tx, file *models.FileuploadFile, c *models.FileuploadCSV) ([]*models.FileuploadPool, error) {
func parseCSVPoollist(ctx context.Context, txn bob.Tx, file *models.FileuploadFile, c *models.FileuploadCSV) ([]*models.FileuploadPool, error) {
pools := make([]*models.FileuploadPool, 0)
r, err := userfile.NewFileReader(userfile.CollectionCSV, file.FileUUID)
if err != nil {
@ -339,45 +297,18 @@ func parseFile(ctx context.Context, txn bob.Tx, file *models.FileuploadFile, c *
line_number = line_number + 1
}
}
func addError(ctx context.Context, txn bob.Tx, c *models.FileuploadCSV, row_number int32, column_number int32, msg string) error {
r, err := models.FileuploadErrorCSVS.Insert(&models.FileuploadErrorCSVSetter{
Col: omit.From(column_number),
CSVFileID: omit.From(c.FileID),
// ID
Line: omit.From(row_number),
Message: omit.From(msg),
}).One(ctx, txn)
func processCSVPoollist(ctx context.Context, txn bob.Tx, file *models.FileuploadFile, c *models.FileuploadCSV, parsed []*models.FileuploadPool) error {
org, err := models.FindOrganization(ctx, db.PGInstance.BobDB, file.OrganizationID)
if err != nil {
return fmt.Errorf("Failed to add error: %w", err)
return fmt.Errorf("get org: %w", err)
}
err = bulkGeocode(ctx, txn, file, c, parsed, org)
if err != nil {
log.Error().Err(err).Msg("Failure during geocoding")
}
log.Info().Int32("id", r.ID).Int32("file_id", c.FileID).Str("msg", msg).Int32("row", row_number).Int32("col", column_number).Msg("Created CSV file error")
return nil
}
func addImportError(file *models.FileuploadFile, err error) {
log.Debug().Err(err).Int32("file_id", file.ID).Msg("Fake add import error")
}
func parseBool(s string) (bool, error) {
sl := strings.ToLower(s)
boolValue, err := strconv.ParseBool(sl)
if err != nil {
// Handle some of the stuff that strconv doesn't handle
switch sl {
case "yes":
return true, nil
case "no":
return false, nil
default:
return false, fmt.Errorf("unrecognized '%s'", sl)
}
}
return boolValue, err
}
func errorMissingHeader(ctx context.Context, txn bob.Tx, c *models.FileuploadCSV, h headerPoolEnum) error {
msg := fmt.Sprintf("The file is missing the '%s' header", h.String())
return addError(ctx, txn, c, 0, 0, msg)
}
func maybeAddServiceArea(req *stadia.StructuredGeocodeRequest, org *models.Organization) {
/*
if org.ServiceAreaXmax.IsNull() ||

42
platform/pdf/pdf.go Normal file
View file

@ -0,0 +1,42 @@
package pdf
import (
"context"
"fmt"
"github.com/Gleipnir-Technology/nidus-sync/config"
"github.com/chromedp/cdproto/page"
"github.com/chromedp/chromedp"
"github.com/rs/zerolog/log"
)
func GeneratePDF(ctx context.Context, code string) ([]byte, error) {
// create context
chrome_ctx, cancel := chromedp.NewContext(context.Background())
defer cancel()
// capture pdf
var buf []byte
url := fmt.Sprintf("http://%s/mailer/%s/preview", config.Bind, code)
log.Info().Str("url", url).Msg("Getting with headless chrome")
if err := chromedp.Run(chrome_ctx, printToPDF(url, &buf)); err != nil {
return nil, fmt.Errorf("print to pdf: %w", err)
}
return buf, nil
}
// print a specific pdf page.
func printToPDF(urlstr string, res *[]byte) chromedp.Tasks {
return chromedp.Tasks{
chromedp.Navigate(urlstr),
chromedp.ActionFunc(func(ctx context.Context) error {
buf, _, err := page.PrintToPDF().WithPrintBackground(false).Do(ctx)
if err != nil {
return err
}
*res = buf
return nil
}),
}
}

View file

@ -44,16 +44,16 @@ type UploadPoolRow struct {
Street string
Tags map[string]string
}
type PoolUpload struct {
type Upload struct {
Created time.Time `db:"created"`
ID int32 `db:"id"`
Status string `db:"status"`
}
func NewPoolUpload(ctx context.Context, u *models.User, upload userfile.FileUpload) (PoolUpload, error) {
func NewUpload(ctx context.Context, u *models.User, upload userfile.FileUpload, t enums.FileuploadCsvtype) (Upload, error) {
txn, err := db.PGInstance.BobDB.BeginTx(ctx, nil)
if err != nil {
return PoolUpload{}, fmt.Errorf("Failed to begin transaction: %w", err)
return Upload{}, fmt.Errorf("Failed to begin transaction: %w", err)
}
defer txn.Rollback(ctx)
@ -69,21 +69,21 @@ func NewPoolUpload(ctx context.Context, u *models.User, upload userfile.FileUplo
FileUUID: omit.From(upload.UUID),
}).One(ctx, txn)
if err != nil {
return PoolUpload{}, fmt.Errorf("Failed to create file upload: %w", err)
return Upload{}, fmt.Errorf("Failed to create file upload: %w", err)
}
_, err = models.FileuploadCSVS.Insert(&models.FileuploadCSVSetter{
Committed: omitnull.FromPtr[time.Time](nil),
FileID: omit.From(file.ID),
Rowcount: omit.From(int32(0)),
Type: omit.From(enums.FileuploadCsvtypePoollist),
Type: omit.From(t),
}).One(ctx, txn)
if err != nil {
return PoolUpload{}, fmt.Errorf("Failed to create csv: %w", err)
return Upload{}, fmt.Errorf("Failed to create csv: %w", err)
}
log.Info().Int32("id", file.ID).Msg("Created new pool CSV upload")
txn.Commit(ctx)
background.ProcessUpload(file.ID)
return PoolUpload{
background.ProcessUpload(file.ID, t)
return Upload{
ID: file.ID,
}, nil
}
@ -115,7 +115,7 @@ func GetUploadPoolDetail(ctx context.Context, organization_id int32, file_id int
if row.Line == 0 {
file_errors = append(file_errors, e)
} else {
log.Info().Int32("line", row.Line).Msg("Found error")
//log.Info().Int32("line", row.Line).Msg("Found error")
by_line, ok := errors_by_line[row.Line]
if !ok {
errors_by_line[row.Line] = []UploadPoolError{e}
@ -175,8 +175,8 @@ func GetUploadPoolDetail(ctx context.Context, organization_id int32, file_id int
Status: file.Status.String(),
}, nil
}
func PoolUploadList(ctx context.Context, organization_id int32) ([]PoolUpload, error) {
results := make([]PoolUpload, 0)
func PoolUploadList(ctx context.Context, organization_id int32) ([]Upload, error) {
results := make([]Upload, 0)
rows, err := bob.All(ctx, db.PGInstance.BobDB, psql.Select(
sm.Columns(
// fileupload.csv columns
@ -200,7 +200,7 @@ func PoolUploadList(ctx context.Context, organization_id int32) ([]PoolUpload, e
sm.From("fileupload.csv").As("csv"),
sm.InnerJoin("fileupload.file").As("file").OnEQ(psql.Raw("csv.file_id"), psql.Raw("file.id")),
sm.Where(psql.Raw("file.organization_id").EQ(psql.Arg(organization_id))),
), scan.StructMapper[PoolUpload]())
), scan.StructMapper[Upload]())
if err != nil {
return results, fmt.Errorf("Failed to query pool upload rows: %w", err)
}

View file

@ -35,6 +35,9 @@ type UploadSummary struct {
Type string `db:"type"`
}
func UploadCommit(ctx context.Context, org *models.Organization, file_id int32) error {
return nil
}
func UploadDiscard(ctx context.Context, org *models.Organization, file_id int32) error {
_, err := psql.Update(
um.Table(models.FileuploadFiles.Alias()),

View file

@ -1,14 +1,16 @@
package sync
import (
"bytes"
"fmt"
"io"
"net/http"
//"strconv"
"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/html"
//"github.com/google/uuid"
"github.com/Gleipnir-Technology/nidus-sync/platform/pdf"
"github.com/go-chi/chi/v5"
)
@ -22,8 +24,26 @@ type contentMailer struct {
ReportURL string
}
// func getMailer(ctx context.Context, r *http.Request, org *models.Organization, user *models.User) (*response[contentMailer], *errorWithStatus) {
func getMailer(w http.ResponseWriter, r *http.Request) {
code := chi.URLParam(r, "code")
if code == "" {
http.Error(w, "empty code", http.StatusBadRequest)
return
}
content, err := pdf.GeneratePDF(r.Context(), code)
if err != nil {
respondError(w, "generate pdf failure", err, http.StatusInternalServerError)
return
}
w.Header().Set("Content-Type", "application/pdf")
disposition := fmt.Sprintf("attachment; filename=\"compliance-mailer-%s.pdf\"", code)
w.Header().Set("Content-Disposition", disposition)
_, err = io.Copy(w, bytes.NewReader(content))
if err != nil {
respondError(w, "copy error", err, http.StatusInternalServerError)
return
}
}
func getMailerPreview(w http.ResponseWriter, r *http.Request) {
code := chi.URLParam(r, "code")

View file

@ -60,11 +60,12 @@ func Router() chi.Router {
r.Method("GET", "/configuration/pesticide/add", authenticatedHandler(getConfigurationPesticideAdd))
r.Method("GET", "/configuration/upload", authenticatedHandler(getUploadList))
r.Method("GET", "/configuration/upload/pool", authenticatedHandler(getUploadPool))
r.Method("GET", "/configuration/upload/pool/bob", authenticatedHandler(getUploadPoolBobCreate))
r.Method("POST", "/configuration/upload/pool/bob", authenticatedHandlerPostMultipart(postUploadPoolBobCreate))
r.Method("GET", "/configuration/upload/pool/flyover", authenticatedHandler(getUploadPoolFlyoverCreate))
r.Method("POST", "/configuration/upload/pool/flyover", authenticatedHandlerPostMultipart(postUploadPoolFlyoverCreate))
r.Method("GET", "/configuration/upload/pool/custom", authenticatedHandler(getUploadPoolCustomCreate))
r.Method("POST", "/configuration/upload/pool/custom", authenticatedHandlerPostMultipart(postUploadPoolCustomCreate))
r.Method("GET", "/configuration/upload/{id}", authenticatedHandler(getUploadByID))
r.Method("POST", "/configuration/upload/{id}/commit", authenticatedHandlerPost(postUploadCommit))
r.Method("POST", "/configuration/upload/{id}/discard", authenticatedHandlerPost(postUploadDiscard))
r.Method("GET", "/configuration/user", authenticatedHandler(getConfigurationUserList))
r.Method("GET", "/configuration/user/add", authenticatedHandler(getConfigurationUserAdd))

View file

@ -6,11 +6,12 @@ import (
"net/http"
"strconv"
"github.com/Gleipnir-Technology/nidus-sync/config"
"github.com/Gleipnir-Technology/nidus-sync/db/enums"
"github.com/Gleipnir-Technology/nidus-sync/db/models"
"github.com/Gleipnir-Technology/nidus-sync/platform"
"github.com/Gleipnir-Technology/nidus-sync/userfile"
"github.com/go-chi/chi/v5"
"github.com/rs/zerolog/log"
)
type contentUploadList struct {
@ -25,25 +26,13 @@ func getUploadList(ctx context.Context, r *http.Request, org *models.Organizatio
}), newErrorMaybe("get upload list: %w", err)
}
type contentUploadURL struct {
Discard string // URL for discarding the upload
}
func newContentUploadURL(id int32) contentUploadURL {
id_str := strconv.FormatInt(int64(id), 10)
return contentUploadURL{
Discard: config.MakeURLNidus("/upload/%s/discard", id_str),
}
}
type contentUploadDetail struct {
CSVFileID int32
Organization *models.Organization
Upload platform.UploadPoolDetail
URL contentUploadURL
}
type contentUploadPoolList struct {
Uploads []platform.PoolUpload
Uploads []platform.Upload
}
type contentUploadPool struct{}
@ -52,11 +41,11 @@ func getUploadPool(ctx context.Context, r *http.Request, org *models.Organizatio
return newResponse("sync/upload-csv-pool.html", data), nil
}
type contentUploadPoolBobCreate struct{}
type contentUploadPoolFlyoverCreate struct{}
func getUploadPoolBobCreate(ctx context.Context, r *http.Request, org *models.Organization, u *models.User) (*response[contentUploadPoolBobCreate], *errorWithStatus) {
data := contentUploadPoolBobCreate{}
return newResponse("sync/upload-csv-pool-bob.html", data), nil
func getUploadPoolFlyoverCreate(ctx context.Context, r *http.Request, org *models.Organization, u *models.User) (*response[contentUploadPoolFlyoverCreate], *errorWithStatus) {
data := contentUploadPoolFlyoverCreate{}
return newResponse("sync/upload-csv-pool-flyover.html", data), nil
}
type contentUploadPoolCustomCreate struct{}
@ -66,6 +55,8 @@ func getUploadPoolCustomCreate(ctx context.Context, r *http.Request, org *models
return newResponse("sync/upload-csv-pool-custom.html", data), nil
}
func getUploadByID(ctx context.Context, r *http.Request, org *models.Organization, u *models.User) (*response[contentUploadDetail], *errorWithStatus) {
test := newContentURLUpload()
log.Info().Str("output", test.Discard(123)).Send()
file_id_str := chi.URLParam(r, "id")
file_id_, err := strconv.ParseInt(file_id_str, 10, 32)
if err != nil {
@ -80,11 +71,25 @@ func getUploadByID(ctx context.Context, r *http.Request, org *models.Organizatio
CSVFileID: file_id,
Organization: org,
Upload: detail,
URL: newContentUploadURL(file_id),
}
return newResponse("sync/upload-by-id.html", data), nil
}
type FormUploadCommit struct{}
func postUploadCommit(ctx context.Context, r *http.Request, org *models.Organization, u *models.User, f FormUploadCommit) (string, *errorWithStatus) {
file_id_str := chi.URLParam(r, "id")
file_id_, err := strconv.ParseInt(file_id_str, 10, 32)
if err != nil {
return "", newError("Failed to parse file_id: %w", err)
}
err = platform.UploadCommit(ctx, org, int32(file_id_))
if err != nil {
return "", newError("Failed to mark discarded: %w", err)
}
return "/configuration/upload", nil
}
type FormUploadDiscard struct{}
func postUploadDiscard(ctx context.Context, r *http.Request, org *models.Organization, u *models.User, f FormUploadDiscard) (string, *errorWithStatus) {
@ -97,13 +102,28 @@ func postUploadDiscard(ctx context.Context, r *http.Request, org *models.Organiz
if err != nil {
return "", newError("Failed to mark discarded: %w", err)
}
return "/upload", nil
return "/configuration/upload", nil
}
type FormUploadPool struct{}
func postUploadPoolBobCreate(ctx context.Context, r *http.Request, org *models.Organization, u *models.User, f FormUploadPool) (string, *errorWithStatus) {
return "", nil
func postUploadPoolFlyoverCreate(ctx context.Context, r *http.Request, org *models.Organization, u *models.User, f FormUploadPool) (string, *errorWithStatus) {
uploads, err := userfile.SaveFileUpload(r, "csvfile", userfile.CollectionCSV)
if err != nil {
return "", newError("Failed to extract image uploads: %s", err)
}
if len(uploads) == 0 {
return "", newErrorStatus(http.StatusBadRequest, "No upload found")
}
if len(uploads) != 1 {
return "", newErrorStatus(http.StatusBadRequest, "You must only submit one file at a time")
}
upload := uploads[0]
saved_upload, err := platform.NewUpload(r.Context(), u, upload, enums.FileuploadCsvtypeFlyover)
if err != nil {
return "", newError("Failed to create new pool: %w", err)
}
return fmt.Sprintf("/configuration/upload/%d", saved_upload.ID), nil
}
func postUploadPoolCustomCreate(ctx context.Context, r *http.Request, org *models.Organization, u *models.User, f FormUploadPool) (string, *errorWithStatus) {
uploads, err := userfile.SaveFileUpload(r, "csvfile", userfile.CollectionCSV)
@ -117,9 +137,9 @@ func postUploadPoolCustomCreate(ctx context.Context, r *http.Request, org *model
return "", newErrorStatus(http.StatusBadRequest, "You must only submit one file at a time")
}
upload := uploads[0]
pool_upload, err := platform.NewPoolUpload(r.Context(), u, upload)
pool_upload, err := platform.NewUpload(r.Context(), u, upload, enums.FileuploadCsvtypePoollist)
if err != nil {
return "", newError("Failed to create new pool: %w", err)
}
return fmt.Sprintf("/upload/%d", pool_upload.ID), nil
return fmt.Sprintf("/configuration/upload/%d", pool_upload.ID), nil
}

View file

@ -1,6 +1,8 @@
package sync
import (
"strconv"
"github.com/Gleipnir-Technology/nidus-sync/config"
)
@ -74,17 +76,29 @@ func newContentURLSidebar() contentURLSidebar {
}
}
type urlForID = func(int) string
func makeURLForID(pattern string) urlForID {
return func(id int) string {
return config.MakeURLNidus(pattern, strconv.Itoa(id))
}
}
type contentURLUpload struct {
Commit urlForID
Discard urlForID
Pool string
PoolBob string
PoolCustom string
PoolFlyover string
SamplePoolCSV string
}
func newContentURLUpload() contentURLUpload {
return contentURLUpload{
Commit: makeURLForID("/configuration/upload/%s/commit"),
Discard: makeURLForID("/configuration/upload/%s/discard"),
Pool: config.MakeURLNidus("/configuration/upload/pool"),
PoolBob: config.MakeURLNidus("/configuration/upload/pool/bob"),
PoolFlyover: config.MakeURLNidus("/configuration/upload/pool/flyover"),
PoolCustom: config.MakeURLNidus("/configuration/upload/pool/custom"),
SamplePoolCSV: config.MakeURLNidus("/static/file/sample-pool.csv"),
}

View file

@ -1,3 +1,12 @@
INSERT INTO compliance_report_request(created, creator, id, public_id, site_id, site_version)
VALUES (NOW(), :user_id, DEFAULT, :public_id, :site_id, 1);
-- INSERT INTO compliance_report_request (created, creator, public_id, site_id, site_version)
-- SELECT
-- NOW(),
-- 1,
-- generate_alphanumeric_code(8),
-- id,
-- version
-- FROM site;

View file

@ -0,0 +1,40 @@
-- This query is just a one-off to quickly get uploaded data turned into sites.
INSERT INTO site (
address_id,
created,
creator_id,
notes,
organization_id,
owner_name,
parcel_id,
tags,
version
)
SELECT DISTINCT ON (closest_address.id)
closest_address.id AS address_id,
fas.created,
fas.creator_id,
'' AS notes,
fas.organization_id,
'' AS owner_name,
containing_parcel.id AS parcel_id,
''::hstore AS tags,
1 AS version
FROM fileupload.flyover_aerial_service fas
CROSS JOIN LATERAL (
SELECT a.id
FROM address a
ORDER BY a.geom <-> fas.geom
LIMIT 1
) closest_address
CROSS JOIN LATERAL (
SELECT p.id
FROM parcel p
WHERE ST_Contains(p.geometry, fas.geom)
LIMIT 1
) containing_parcel
WHERE fas.geom IS NOT NULL
AND fas.deleted IS NULL
ORDER BY closest_address.id, fas.created ASC -- Keep the earliest created per address
ON CONFLICT (address_id) DO NOTHING; -- Skip if address already has a site