diff --git a/db/dberrors/publicreport.report_log.bob.go b/db/dberrors/publicreport.report_log.bob.go new file mode 100644 index 00000000..8e5b800a --- /dev/null +++ b/db/dberrors/publicreport.report_log.bob.go @@ -0,0 +1,17 @@ +// Code generated by BobGen psql v0.42.5. DO NOT EDIT. +// This file is meant to be re-generated in place and/or deleted at any time. + +package dberrors + +var PublicreportReportLogErrors = &publicreportReportLogErrors{ + ErrUniqueReportLogPkey: &UniqueConstraintError{ + schema: "publicreport", + table: "report_log", + columns: []string{"id"}, + s: "report_log_pkey", + }, +} + +type publicreportReportLogErrors struct { + ErrUniqueReportLogPkey *UniqueConstraintError +} diff --git a/db/dbinfo/publicreport.report_log.bob.go b/db/dbinfo/publicreport.report_log.bob.go new file mode 100644 index 00000000..75e1f4b8 --- /dev/null +++ b/db/dbinfo/publicreport.report_log.bob.go @@ -0,0 +1,197 @@ +// 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 PublicreportReportLogs = Table[ + publicreportReportLogColumns, + publicreportReportLogIndexes, + publicreportReportLogForeignKeys, + publicreportReportLogUniques, + publicreportReportLogChecks, +]{ + Schema: "publicreport", + Name: "report_log", + Columns: publicreportReportLogColumns{ + Created: column{ + Name: "created", + DBType: "timestamp without time zone", + Default: "", + Comment: "", + Nullable: false, + Generated: false, + AutoIncr: false, + }, + EmailLogID: column{ + Name: "email_log_id", + DBType: "integer", + Default: "NULL", + Comment: "", + Nullable: true, + Generated: false, + AutoIncr: false, + }, + ID: column{ + Name: "id", + DBType: "integer", + Default: "nextval('publicreport.report_log_id_seq'::regclass)", + Comment: "", + Nullable: false, + Generated: false, + AutoIncr: false, + }, + ReportID: column{ + Name: "report_id", + DBType: "integer", + Default: "", + Comment: "", + Nullable: false, + Generated: false, + AutoIncr: false, + }, + TextLogID: column{ + Name: "text_log_id", + DBType: "integer", + Default: "NULL", + Comment: "", + Nullable: true, + Generated: false, + AutoIncr: false, + }, + Type: column{ + Name: "type_", + DBType: "publicreport.reportlogtype", + Default: "", + Comment: "", + Nullable: false, + Generated: false, + AutoIncr: false, + }, + UserID: column{ + Name: "user_id", + DBType: "integer", + Default: "NULL", + Comment: "", + Nullable: true, + Generated: false, + AutoIncr: false, + }, + }, + Indexes: publicreportReportLogIndexes{ + ReportLogPkey: index{ + Type: "btree", + Name: "report_log_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: "report_log_pkey", + Columns: []string{"id"}, + Comment: "", + }, + ForeignKeys: publicreportReportLogForeignKeys{ + PublicreportReportLogReportLogEmailLogIDFkey: foreignKey{ + constraint: constraint{ + Name: "publicreport.report_log.report_log_email_log_id_fkey", + Columns: []string{"email_log_id"}, + Comment: "", + }, + ForeignTable: "comms.email_log", + ForeignColumns: []string{"id"}, + }, + PublicreportReportLogReportLogReportIDFkey: foreignKey{ + constraint: constraint{ + Name: "publicreport.report_log.report_log_report_id_fkey", + Columns: []string{"report_id"}, + Comment: "", + }, + ForeignTable: "publicreport.report", + ForeignColumns: []string{"id"}, + }, + PublicreportReportLogReportLogTextLogIDFkey: foreignKey{ + constraint: constraint{ + Name: "publicreport.report_log.report_log_text_log_id_fkey", + Columns: []string{"text_log_id"}, + Comment: "", + }, + ForeignTable: "comms.text_log", + ForeignColumns: []string{"id"}, + }, + PublicreportReportLogReportLogUserIDFkey: foreignKey{ + constraint: constraint{ + Name: "publicreport.report_log.report_log_user_id_fkey", + Columns: []string{"user_id"}, + Comment: "", + }, + ForeignTable: "user_", + ForeignColumns: []string{"id"}, + }, + }, + + Comment: "", +} + +type publicreportReportLogColumns struct { + Created column + EmailLogID column + ID column + ReportID column + TextLogID column + Type column + UserID column +} + +func (c publicreportReportLogColumns) AsSlice() []column { + return []column{ + c.Created, c.EmailLogID, c.ID, c.ReportID, c.TextLogID, c.Type, c.UserID, + } +} + +type publicreportReportLogIndexes struct { + ReportLogPkey index +} + +func (i publicreportReportLogIndexes) AsSlice() []index { + return []index{ + i.ReportLogPkey, + } +} + +type publicreportReportLogForeignKeys struct { + PublicreportReportLogReportLogEmailLogIDFkey foreignKey + PublicreportReportLogReportLogReportIDFkey foreignKey + PublicreportReportLogReportLogTextLogIDFkey foreignKey + PublicreportReportLogReportLogUserIDFkey foreignKey +} + +func (f publicreportReportLogForeignKeys) AsSlice() []foreignKey { + return []foreignKey{ + f.PublicreportReportLogReportLogEmailLogIDFkey, f.PublicreportReportLogReportLogReportIDFkey, f.PublicreportReportLogReportLogTextLogIDFkey, f.PublicreportReportLogReportLogUserIDFkey, + } +} + +type publicreportReportLogUniques struct{} + +func (u publicreportReportLogUniques) AsSlice() []constraint { + return []constraint{} +} + +type publicreportReportLogChecks struct{} + +func (c publicreportReportLogChecks) AsSlice() []check { + return []check{} +} diff --git a/db/enums/enums.bob.go b/db/enums/enums.bob.go index eeb2d051..4537c154 100644 --- a/db/enums/enums.bob.go +++ b/db/enums/enums.bob.go @@ -1966,6 +1966,94 @@ func (e *PublicreportPoolsourceduration) Scan(value any) error { return nil } +// Enum values for PublicreportReportlogtype +const ( + PublicreportReportlogtypeCreated PublicreportReportlogtype = "created" + PublicreportReportlogtypeInvalidated PublicreportReportlogtype = "invalidated" + PublicreportReportlogtypeMessageEmail PublicreportReportlogtype = "message-email" + PublicreportReportlogtypeMessageText PublicreportReportlogtype = "message-text" + PublicreportReportlogtypeReviewed PublicreportReportlogtype = "reviewed" + PublicreportReportlogtypeScheduled PublicreportReportlogtype = "scheduled" + PublicreportReportlogtypeTreated PublicreportReportlogtype = "treated" +) + +func AllPublicreportReportlogtype() []PublicreportReportlogtype { + return []PublicreportReportlogtype{ + PublicreportReportlogtypeCreated, + PublicreportReportlogtypeInvalidated, + PublicreportReportlogtypeMessageEmail, + PublicreportReportlogtypeMessageText, + PublicreportReportlogtypeReviewed, + PublicreportReportlogtypeScheduled, + PublicreportReportlogtypeTreated, + } +} + +type PublicreportReportlogtype string + +func (e PublicreportReportlogtype) String() string { + return string(e) +} + +func (e PublicreportReportlogtype) Valid() bool { + switch e { + case PublicreportReportlogtypeCreated, + PublicreportReportlogtypeInvalidated, + PublicreportReportlogtypeMessageEmail, + PublicreportReportlogtypeMessageText, + PublicreportReportlogtypeReviewed, + PublicreportReportlogtypeScheduled, + PublicreportReportlogtypeTreated: + return true + default: + return false + } +} + +// useful when testing in other packages +func (e PublicreportReportlogtype) All() []PublicreportReportlogtype { + return AllPublicreportReportlogtype() +} + +func (e PublicreportReportlogtype) MarshalText() ([]byte, error) { + return []byte(e), nil +} + +func (e *PublicreportReportlogtype) UnmarshalText(text []byte) error { + return e.Scan(text) +} + +func (e PublicreportReportlogtype) MarshalBinary() ([]byte, error) { + return []byte(e), nil +} + +func (e *PublicreportReportlogtype) UnmarshalBinary(data []byte) error { + return e.Scan(data) +} + +func (e PublicreportReportlogtype) Value() (driver.Value, error) { + return string(e), nil +} + +func (e *PublicreportReportlogtype) Scan(value any) error { + switch x := value.(type) { + case string: + *e = PublicreportReportlogtype(x) + case []byte: + *e = PublicreportReportlogtype(x) + case nil: + return fmt.Errorf("cannot nil into PublicreportReportlogtype") + default: + return fmt.Errorf("cannot scan type %T: %v", value, value) + } + + if !e.Valid() { + return fmt.Errorf("invalid PublicreportReportlogtype value: %s", *e) + } + + return nil +} + // Enum values for PublicreportReportstatustype const ( PublicreportReportstatustypeReported PublicreportReportstatustype = "reported" diff --git a/db/migrations/00114_publicreport_report_log.sql b/db/migrations/00114_publicreport_report_log.sql new file mode 100644 index 00000000..1611b52e --- /dev/null +++ b/db/migrations/00114_publicreport_report_log.sql @@ -0,0 +1,39 @@ +-- +goose UP +CREATE TYPE publicreport.ReportLogType AS ENUM ( + 'created', + 'invalidated', + 'message-email', + 'message-text', + 'reviewed', + 'scheduled', + 'treated' +); +CREATE TABLE publicreport.report_log ( + created TIMESTAMP WITHOUT TIME ZONE NOT NULL, + email_log_id INTEGER REFERENCES comms.email_log(id), + id SERIAL NOT NULL, + report_id INTEGER NOT NULL REFERENCES publicreport.report(id), + text_log_id INTEGER REFERENCES comms.text_log(id), + type_ publicreport.ReportLogType NOT NULL, + user_id INTEGER REFERENCES user_(id), + PRIMARY KEY (id) +); +INSERT INTO publicreport.report_log ( + created, + email_log_id, + report_id, + text_log_id, + type_, + user_id +) +SELECT + created, + NULL, + id, + NULL, + 'created', + NULL +FROM publicreport.report; +-- +goose Down +DROP TABLE publicreport.report_log; +DROP TYPE publicreport.ReportLogType; diff --git a/db/models/bob_loaders.bob.go b/db/models/bob_loaders.bob.go index b4ab13b0..f01efa6c 100644 --- a/db/models/bob_loaders.bob.go +++ b/db/models/bob_loaders.bob.go @@ -98,6 +98,7 @@ type preloaders struct { PublicreportNuisanceOld publicreportNuisanceOldPreloader PublicreportReport publicreportReportPreloader PublicreportReportImage publicreportReportImagePreloader + PublicreportReportLog publicreportReportLogPreloader PublicreportSubscribeEmail publicreportSubscribeEmailPreloader PublicreportSubscribePhone publicreportSubscribePhonePreloader PublicreportWater publicreportWaterPreloader @@ -196,6 +197,7 @@ func getPreloaders() preloaders { PublicreportNuisanceOld: buildPublicreportNuisanceOldPreloader(), PublicreportReport: buildPublicreportReportPreloader(), PublicreportReportImage: buildPublicreportReportImagePreloader(), + PublicreportReportLog: buildPublicreportReportLogPreloader(), PublicreportSubscribeEmail: buildPublicreportSubscribeEmailPreloader(), PublicreportSubscribePhone: buildPublicreportSubscribePhonePreloader(), PublicreportWater: buildPublicreportWaterPreloader(), @@ -300,6 +302,7 @@ type thenLoaders[Q orm.Loadable] struct { PublicreportNuisanceOld publicreportNuisanceOldThenLoader[Q] PublicreportReport publicreportReportThenLoader[Q] PublicreportReportImage publicreportReportImageThenLoader[Q] + PublicreportReportLog publicreportReportLogThenLoader[Q] PublicreportSubscribeEmail publicreportSubscribeEmailThenLoader[Q] PublicreportSubscribePhone publicreportSubscribePhoneThenLoader[Q] PublicreportWater publicreportWaterThenLoader[Q] @@ -398,6 +401,7 @@ func getThenLoaders[Q orm.Loadable]() thenLoaders[Q] { PublicreportNuisanceOld: buildPublicreportNuisanceOldThenLoader[Q](), PublicreportReport: buildPublicreportReportThenLoader[Q](), PublicreportReportImage: buildPublicreportReportImageThenLoader[Q](), + PublicreportReportLog: buildPublicreportReportLogThenLoader[Q](), PublicreportSubscribeEmail: buildPublicreportSubscribeEmailThenLoader[Q](), PublicreportSubscribePhone: buildPublicreportSubscribePhoneThenLoader[Q](), PublicreportWater: buildPublicreportWaterThenLoader[Q](), diff --git a/db/models/bob_where.bob.go b/db/models/bob_where.bob.go index b3405205..42915d22 100644 --- a/db/models/bob_where.bob.go +++ b/db/models/bob_where.bob.go @@ -104,6 +104,7 @@ func Where[Q psql.Filterable]() struct { PublicreportReports publicreportReportWhere[Q] PublicreportReportImages publicreportReportImageWhere[Q] PublicreportReportLocations publicreportReportLocationWhere[Q] + PublicreportReportLogs publicreportReportLogWhere[Q] PublicreportSubscribeEmails publicreportSubscribeEmailWhere[Q] PublicreportSubscribePhones publicreportSubscribePhoneWhere[Q] PublicreportWaters publicreportWaterWhere[Q] @@ -210,6 +211,7 @@ func Where[Q psql.Filterable]() struct { PublicreportReports publicreportReportWhere[Q] PublicreportReportImages publicreportReportImageWhere[Q] PublicreportReportLocations publicreportReportLocationWhere[Q] + PublicreportReportLogs publicreportReportLogWhere[Q] PublicreportSubscribeEmails publicreportSubscribeEmailWhere[Q] PublicreportSubscribePhones publicreportSubscribePhoneWhere[Q] PublicreportWaters publicreportWaterWhere[Q] @@ -315,6 +317,7 @@ func Where[Q psql.Filterable]() struct { PublicreportReports: buildPublicreportReportWhere[Q](PublicreportReports.Columns), PublicreportReportImages: buildPublicreportReportImageWhere[Q](PublicreportReportImages.Columns), PublicreportReportLocations: buildPublicreportReportLocationWhere[Q](PublicreportReportLocations.Columns), + PublicreportReportLogs: buildPublicreportReportLogWhere[Q](PublicreportReportLogs.Columns), PublicreportSubscribeEmails: buildPublicreportSubscribeEmailWhere[Q](PublicreportSubscribeEmails.Columns), PublicreportSubscribePhones: buildPublicreportSubscribePhoneWhere[Q](PublicreportSubscribePhones.Columns), PublicreportWaters: buildPublicreportWaterWhere[Q](PublicreportWaters.Columns), diff --git a/db/models/comms.email_log.bob.go b/db/models/comms.email_log.bob.go index 7b225d33..92314eec 100644 --- a/db/models/comms.email_log.bob.go +++ b/db/models/comms.email_log.bob.go @@ -53,8 +53,9 @@ type CommsEmailLogsQuery = *psql.ViewQuery[*CommsEmailLog, CommsEmailLogSlice] // commsEmailLogR is where relationships are stored. type commsEmailLogR struct { - DestinationEmailContact *CommsEmailContact // comms.email_log.email_log_destination_fkey - TemplateEmailTemplate *CommsEmailTemplate // comms.email_log.email_log_template_id_fkey + DestinationEmailContact *CommsEmailContact // comms.email_log.email_log_destination_fkey + TemplateEmailTemplate *CommsEmailTemplate // comms.email_log.email_log_template_id_fkey + ReportLogs PublicreportReportLogSlice // publicreport.report_log.report_log_email_log_id_fkey } func buildCommsEmailLogColumns(alias string) commsEmailLogColumns { @@ -627,6 +628,30 @@ func (os CommsEmailLogSlice) TemplateEmailTemplate(mods ...bob.Mod[*dialect.Sele )...) } +// ReportLogs starts a query for related objects on publicreport.report_log +func (o *CommsEmailLog) ReportLogs(mods ...bob.Mod[*dialect.SelectQuery]) PublicreportReportLogsQuery { + return PublicreportReportLogs.Query(append(mods, + sm.Where(PublicreportReportLogs.Columns.EmailLogID.EQ(psql.Arg(o.ID))), + )...) +} + +func (os CommsEmailLogSlice) ReportLogs(mods ...bob.Mod[*dialect.SelectQuery]) PublicreportReportLogsQuery { + 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 PublicreportReportLogs.Query(append(mods, + sm.Where(psql.Group(PublicreportReportLogs.Columns.EmailLogID).OP("IN", PKArgExpr)), + )...) +} + func attachCommsEmailLogDestinationEmailContact0(ctx context.Context, exec bob.Executor, count int, commsEmailLog0 *CommsEmailLog, commsEmailContact1 *CommsEmailContact) (*CommsEmailLog, error) { setter := &CommsEmailLogSetter{ Destination: omit.From(commsEmailContact1.Address), @@ -723,6 +748,74 @@ func (commsEmailLog0 *CommsEmailLog) AttachTemplateEmailTemplate(ctx context.Con return nil } +func insertCommsEmailLogReportLogs0(ctx context.Context, exec bob.Executor, publicreportReportLogs1 []*PublicreportReportLogSetter, commsEmailLog0 *CommsEmailLog) (PublicreportReportLogSlice, error) { + for i := range publicreportReportLogs1 { + publicreportReportLogs1[i].EmailLogID = omitnull.From(commsEmailLog0.ID) + } + + ret, err := PublicreportReportLogs.Insert(bob.ToMods(publicreportReportLogs1...)).All(ctx, exec) + if err != nil { + return ret, fmt.Errorf("insertCommsEmailLogReportLogs0: %w", err) + } + + return ret, nil +} + +func attachCommsEmailLogReportLogs0(ctx context.Context, exec bob.Executor, count int, publicreportReportLogs1 PublicreportReportLogSlice, commsEmailLog0 *CommsEmailLog) (PublicreportReportLogSlice, error) { + setter := &PublicreportReportLogSetter{ + EmailLogID: omitnull.From(commsEmailLog0.ID), + } + + err := publicreportReportLogs1.UpdateAll(ctx, exec, *setter) + if err != nil { + return nil, fmt.Errorf("attachCommsEmailLogReportLogs0: %w", err) + } + + return publicreportReportLogs1, nil +} + +func (commsEmailLog0 *CommsEmailLog) InsertReportLogs(ctx context.Context, exec bob.Executor, related ...*PublicreportReportLogSetter) error { + if len(related) == 0 { + return nil + } + + var err error + + publicreportReportLogs1, err := insertCommsEmailLogReportLogs0(ctx, exec, related, commsEmailLog0) + if err != nil { + return err + } + + commsEmailLog0.R.ReportLogs = append(commsEmailLog0.R.ReportLogs, publicreportReportLogs1...) + + for _, rel := range publicreportReportLogs1 { + rel.R.EmailLog = commsEmailLog0 + } + return nil +} + +func (commsEmailLog0 *CommsEmailLog) AttachReportLogs(ctx context.Context, exec bob.Executor, related ...*PublicreportReportLog) error { + if len(related) == 0 { + return nil + } + + var err error + publicreportReportLogs1 := PublicreportReportLogSlice(related) + + _, err = attachCommsEmailLogReportLogs0(ctx, exec, len(related), publicreportReportLogs1, commsEmailLog0) + if err != nil { + return err + } + + commsEmailLog0.R.ReportLogs = append(commsEmailLog0.R.ReportLogs, publicreportReportLogs1...) + + for _, rel := range related { + rel.R.EmailLog = commsEmailLog0 + } + + return nil +} + type commsEmailLogWhere[Q psql.Filterable] struct { ID psql.WhereMod[Q, int32] Created psql.WhereMod[Q, time.Time] @@ -787,6 +880,20 @@ func (o *CommsEmailLog) Preload(name string, retrieved any) error { rel.R.TemplateEmailLogs = CommsEmailLogSlice{o} } return nil + case "ReportLogs": + rels, ok := retrieved.(PublicreportReportLogSlice) + if !ok { + return fmt.Errorf("commsEmailLog cannot load %T as %q", retrieved, name) + } + + o.R.ReportLogs = rels + + for _, rel := range rels { + if rel != nil { + rel.R.EmailLog = o + } + } + return nil default: return fmt.Errorf("commsEmailLog has no relationship %q", name) } @@ -831,6 +938,7 @@ func buildCommsEmailLogPreloader() commsEmailLogPreloader { type commsEmailLogThenLoader[Q orm.Loadable] struct { DestinationEmailContact func(...bob.Mod[*dialect.SelectQuery]) orm.Loader[Q] TemplateEmailTemplate func(...bob.Mod[*dialect.SelectQuery]) orm.Loader[Q] + ReportLogs func(...bob.Mod[*dialect.SelectQuery]) orm.Loader[Q] } func buildCommsEmailLogThenLoader[Q orm.Loadable]() commsEmailLogThenLoader[Q] { @@ -840,6 +948,9 @@ func buildCommsEmailLogThenLoader[Q orm.Loadable]() commsEmailLogThenLoader[Q] { type TemplateEmailTemplateLoadInterface interface { LoadTemplateEmailTemplate(context.Context, bob.Executor, ...bob.Mod[*dialect.SelectQuery]) error } + type ReportLogsLoadInterface interface { + LoadReportLogs(context.Context, bob.Executor, ...bob.Mod[*dialect.SelectQuery]) error + } return commsEmailLogThenLoader[Q]{ DestinationEmailContact: thenLoadBuilder[Q]( @@ -854,6 +965,12 @@ func buildCommsEmailLogThenLoader[Q orm.Loadable]() commsEmailLogThenLoader[Q] { return retrieved.LoadTemplateEmailTemplate(ctx, exec, mods...) }, ), + ReportLogs: thenLoadBuilder[Q]( + "ReportLogs", + func(ctx context.Context, exec bob.Executor, retrieved ReportLogsLoadInterface, mods ...bob.Mod[*dialect.SelectQuery]) error { + return retrieved.LoadReportLogs(ctx, exec, mods...) + }, + ), } } @@ -960,3 +1077,67 @@ func (os CommsEmailLogSlice) LoadTemplateEmailTemplate(ctx context.Context, exec return nil } + +// LoadReportLogs loads the commsEmailLog's ReportLogs into the .R struct +func (o *CommsEmailLog) LoadReportLogs(ctx context.Context, exec bob.Executor, mods ...bob.Mod[*dialect.SelectQuery]) error { + if o == nil { + return nil + } + + // Reset the relationship + o.R.ReportLogs = nil + + related, err := o.ReportLogs(mods...).All(ctx, exec) + if err != nil { + return err + } + + for _, rel := range related { + rel.R.EmailLog = o + } + + o.R.ReportLogs = related + return nil +} + +// LoadReportLogs loads the commsEmailLog's ReportLogs into the .R struct +func (os CommsEmailLogSlice) LoadReportLogs(ctx context.Context, exec bob.Executor, mods ...bob.Mod[*dialect.SelectQuery]) error { + if len(os) == 0 { + return nil + } + + publicreportReportLogs, err := os.ReportLogs(mods...).All(ctx, exec) + if err != nil { + return err + } + + for _, o := range os { + if o == nil { + continue + } + + o.R.ReportLogs = nil + } + + for _, o := range os { + if o == nil { + continue + } + + for _, rel := range publicreportReportLogs { + + if !rel.EmailLogID.IsValue() { + continue + } + if !(rel.EmailLogID.IsValue() && o.ID == rel.EmailLogID.MustGet()) { + continue + } + + rel.R.EmailLog = o + + o.R.ReportLogs = append(o.R.ReportLogs, rel) + } + } + + return nil +} diff --git a/db/models/comms.text_log.bob.go b/db/models/comms.text_log.bob.go index 85076201..10d2af05 100644 --- a/db/models/comms.text_log.bob.go +++ b/db/models/comms.text_log.bob.go @@ -52,9 +52,10 @@ type CommsTextLogsQuery = *psql.ViewQuery[*CommsTextLog, CommsTextLogSlice] // commsTextLogR is where relationships are stored. type commsTextLogR struct { - DestinationPhone *CommsPhone // comms.text_log.text_log_destination_fkey - SourcePhone *CommsPhone // comms.text_log.text_log_source_fkey - ReportTexts ReportTextSlice // report_text.report_text_text_log_id_fkey + DestinationPhone *CommsPhone // comms.text_log.text_log_destination_fkey + SourcePhone *CommsPhone // comms.text_log.text_log_source_fkey + ReportLogs PublicreportReportLogSlice // publicreport.report_log.report_log_text_log_id_fkey + ReportTexts ReportTextSlice // report_text.report_text_text_log_id_fkey } func buildCommsTextLogColumns(alias string) commsTextLogColumns { @@ -605,6 +606,30 @@ func (os CommsTextLogSlice) SourcePhone(mods ...bob.Mod[*dialect.SelectQuery]) C )...) } +// ReportLogs starts a query for related objects on publicreport.report_log +func (o *CommsTextLog) ReportLogs(mods ...bob.Mod[*dialect.SelectQuery]) PublicreportReportLogsQuery { + return PublicreportReportLogs.Query(append(mods, + sm.Where(PublicreportReportLogs.Columns.TextLogID.EQ(psql.Arg(o.ID))), + )...) +} + +func (os CommsTextLogSlice) ReportLogs(mods ...bob.Mod[*dialect.SelectQuery]) PublicreportReportLogsQuery { + 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 PublicreportReportLogs.Query(append(mods, + sm.Where(psql.Group(PublicreportReportLogs.Columns.TextLogID).OP("IN", PKArgExpr)), + )...) +} + // ReportTexts starts a query for related objects on report_text func (o *CommsTextLog) ReportTexts(mods ...bob.Mod[*dialect.SelectQuery]) ReportTextsQuery { return ReportTexts.Query(append(mods, @@ -725,6 +750,74 @@ func (commsTextLog0 *CommsTextLog) AttachSourcePhone(ctx context.Context, exec b return nil } +func insertCommsTextLogReportLogs0(ctx context.Context, exec bob.Executor, publicreportReportLogs1 []*PublicreportReportLogSetter, commsTextLog0 *CommsTextLog) (PublicreportReportLogSlice, error) { + for i := range publicreportReportLogs1 { + publicreportReportLogs1[i].TextLogID = omitnull.From(commsTextLog0.ID) + } + + ret, err := PublicreportReportLogs.Insert(bob.ToMods(publicreportReportLogs1...)).All(ctx, exec) + if err != nil { + return ret, fmt.Errorf("insertCommsTextLogReportLogs0: %w", err) + } + + return ret, nil +} + +func attachCommsTextLogReportLogs0(ctx context.Context, exec bob.Executor, count int, publicreportReportLogs1 PublicreportReportLogSlice, commsTextLog0 *CommsTextLog) (PublicreportReportLogSlice, error) { + setter := &PublicreportReportLogSetter{ + TextLogID: omitnull.From(commsTextLog0.ID), + } + + err := publicreportReportLogs1.UpdateAll(ctx, exec, *setter) + if err != nil { + return nil, fmt.Errorf("attachCommsTextLogReportLogs0: %w", err) + } + + return publicreportReportLogs1, nil +} + +func (commsTextLog0 *CommsTextLog) InsertReportLogs(ctx context.Context, exec bob.Executor, related ...*PublicreportReportLogSetter) error { + if len(related) == 0 { + return nil + } + + var err error + + publicreportReportLogs1, err := insertCommsTextLogReportLogs0(ctx, exec, related, commsTextLog0) + if err != nil { + return err + } + + commsTextLog0.R.ReportLogs = append(commsTextLog0.R.ReportLogs, publicreportReportLogs1...) + + for _, rel := range publicreportReportLogs1 { + rel.R.TextLog = commsTextLog0 + } + return nil +} + +func (commsTextLog0 *CommsTextLog) AttachReportLogs(ctx context.Context, exec bob.Executor, related ...*PublicreportReportLog) error { + if len(related) == 0 { + return nil + } + + var err error + publicreportReportLogs1 := PublicreportReportLogSlice(related) + + _, err = attachCommsTextLogReportLogs0(ctx, exec, len(related), publicreportReportLogs1, commsTextLog0) + if err != nil { + return err + } + + commsTextLog0.R.ReportLogs = append(commsTextLog0.R.ReportLogs, publicreportReportLogs1...) + + for _, rel := range related { + rel.R.TextLog = commsTextLog0 + } + + return nil +} + func insertCommsTextLogReportTexts0(ctx context.Context, exec bob.Executor, reportTexts1 []*ReportTextSetter, commsTextLog0 *CommsTextLog) (ReportTextSlice, error) { for i := range reportTexts1 { reportTexts1[i].TextLogID = omit.From(commsTextLog0.ID) @@ -855,6 +948,20 @@ func (o *CommsTextLog) Preload(name string, retrieved any) error { rel.R.SourceTextLogs = CommsTextLogSlice{o} } return nil + case "ReportLogs": + rels, ok := retrieved.(PublicreportReportLogSlice) + if !ok { + return fmt.Errorf("commsTextLog cannot load %T as %q", retrieved, name) + } + + o.R.ReportLogs = rels + + for _, rel := range rels { + if rel != nil { + rel.R.TextLog = o + } + } + return nil case "ReportTexts": rels, ok := retrieved.(ReportTextSlice) if !ok { @@ -913,6 +1020,7 @@ func buildCommsTextLogPreloader() commsTextLogPreloader { type commsTextLogThenLoader[Q orm.Loadable] struct { DestinationPhone func(...bob.Mod[*dialect.SelectQuery]) orm.Loader[Q] SourcePhone func(...bob.Mod[*dialect.SelectQuery]) orm.Loader[Q] + ReportLogs func(...bob.Mod[*dialect.SelectQuery]) orm.Loader[Q] ReportTexts func(...bob.Mod[*dialect.SelectQuery]) orm.Loader[Q] } @@ -923,6 +1031,9 @@ func buildCommsTextLogThenLoader[Q orm.Loadable]() commsTextLogThenLoader[Q] { type SourcePhoneLoadInterface interface { LoadSourcePhone(context.Context, bob.Executor, ...bob.Mod[*dialect.SelectQuery]) error } + type ReportLogsLoadInterface interface { + LoadReportLogs(context.Context, bob.Executor, ...bob.Mod[*dialect.SelectQuery]) error + } type ReportTextsLoadInterface interface { LoadReportTexts(context.Context, bob.Executor, ...bob.Mod[*dialect.SelectQuery]) error } @@ -940,6 +1051,12 @@ func buildCommsTextLogThenLoader[Q orm.Loadable]() commsTextLogThenLoader[Q] { return retrieved.LoadSourcePhone(ctx, exec, mods...) }, ), + ReportLogs: thenLoadBuilder[Q]( + "ReportLogs", + func(ctx context.Context, exec bob.Executor, retrieved ReportLogsLoadInterface, mods ...bob.Mod[*dialect.SelectQuery]) error { + return retrieved.LoadReportLogs(ctx, exec, mods...) + }, + ), ReportTexts: thenLoadBuilder[Q]( "ReportTexts", func(ctx context.Context, exec bob.Executor, retrieved ReportTextsLoadInterface, mods ...bob.Mod[*dialect.SelectQuery]) error { @@ -1053,6 +1170,70 @@ func (os CommsTextLogSlice) LoadSourcePhone(ctx context.Context, exec bob.Execut return nil } +// LoadReportLogs loads the commsTextLog's ReportLogs into the .R struct +func (o *CommsTextLog) LoadReportLogs(ctx context.Context, exec bob.Executor, mods ...bob.Mod[*dialect.SelectQuery]) error { + if o == nil { + return nil + } + + // Reset the relationship + o.R.ReportLogs = nil + + related, err := o.ReportLogs(mods...).All(ctx, exec) + if err != nil { + return err + } + + for _, rel := range related { + rel.R.TextLog = o + } + + o.R.ReportLogs = related + return nil +} + +// LoadReportLogs loads the commsTextLog's ReportLogs into the .R struct +func (os CommsTextLogSlice) LoadReportLogs(ctx context.Context, exec bob.Executor, mods ...bob.Mod[*dialect.SelectQuery]) error { + if len(os) == 0 { + return nil + } + + publicreportReportLogs, err := os.ReportLogs(mods...).All(ctx, exec) + if err != nil { + return err + } + + for _, o := range os { + if o == nil { + continue + } + + o.R.ReportLogs = nil + } + + for _, o := range os { + if o == nil { + continue + } + + for _, rel := range publicreportReportLogs { + + if !rel.TextLogID.IsValue() { + continue + } + if !(rel.TextLogID.IsValue() && o.ID == rel.TextLogID.MustGet()) { + continue + } + + rel.R.TextLog = o + + o.R.ReportLogs = append(o.R.ReportLogs, rel) + } + } + + return nil +} + // LoadReportTexts loads the commsTextLog's ReportTexts into the .R struct func (o *CommsTextLog) LoadReportTexts(ctx context.Context, exec bob.Executor, mods ...bob.Mod[*dialect.SelectQuery]) error { if o == nil { diff --git a/db/models/publicreport.report.bob.go b/db/models/publicreport.report.bob.go index c7392260..eaccca9a 100644 --- a/db/models/publicreport.report.bob.go +++ b/db/models/publicreport.report.bob.go @@ -76,6 +76,7 @@ type publicreportReportR struct { Organization *Organization // publicreport.report.report_organization_id_fkey ReviewerUser *User // publicreport.report.report_reviewer_id_fkey Images PublicreportImageSlice // publicreport.report_image.report_image_image_id_fkeypublicreport.report_image.report_image_report_id_fkey + ReportLogs PublicreportReportLogSlice // publicreport.report_log.report_log_report_id_fkey Water *PublicreportWater // publicreport.water.water_report_id_fkey ReportTexts ReportTextSlice // report_text.report_text_report_id_fkey } @@ -1107,6 +1108,30 @@ func (os PublicreportReportSlice) Images(mods ...bob.Mod[*dialect.SelectQuery]) )...) } +// ReportLogs starts a query for related objects on publicreport.report_log +func (o *PublicreportReport) ReportLogs(mods ...bob.Mod[*dialect.SelectQuery]) PublicreportReportLogsQuery { + return PublicreportReportLogs.Query(append(mods, + sm.Where(PublicreportReportLogs.Columns.ReportID.EQ(psql.Arg(o.ID))), + )...) +} + +func (os PublicreportReportSlice) ReportLogs(mods ...bob.Mod[*dialect.SelectQuery]) PublicreportReportLogsQuery { + 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 PublicreportReportLogs.Query(append(mods, + sm.Where(psql.Group(PublicreportReportLogs.Columns.ReportID).OP("IN", PKArgExpr)), + )...) +} + // Water starts a query for related objects on publicreport.water func (o *PublicreportReport) Water(mods ...bob.Mod[*dialect.SelectQuery]) PublicreportWatersQuery { return PublicreportWaters.Query(append(mods, @@ -1622,6 +1647,74 @@ func (publicreportReport0 *PublicreportReport) AttachImages(ctx context.Context, return nil } +func insertPublicreportReportReportLogs0(ctx context.Context, exec bob.Executor, publicreportReportLogs1 []*PublicreportReportLogSetter, publicreportReport0 *PublicreportReport) (PublicreportReportLogSlice, error) { + for i := range publicreportReportLogs1 { + publicreportReportLogs1[i].ReportID = omit.From(publicreportReport0.ID) + } + + ret, err := PublicreportReportLogs.Insert(bob.ToMods(publicreportReportLogs1...)).All(ctx, exec) + if err != nil { + return ret, fmt.Errorf("insertPublicreportReportReportLogs0: %w", err) + } + + return ret, nil +} + +func attachPublicreportReportReportLogs0(ctx context.Context, exec bob.Executor, count int, publicreportReportLogs1 PublicreportReportLogSlice, publicreportReport0 *PublicreportReport) (PublicreportReportLogSlice, error) { + setter := &PublicreportReportLogSetter{ + ReportID: omit.From(publicreportReport0.ID), + } + + err := publicreportReportLogs1.UpdateAll(ctx, exec, *setter) + if err != nil { + return nil, fmt.Errorf("attachPublicreportReportReportLogs0: %w", err) + } + + return publicreportReportLogs1, nil +} + +func (publicreportReport0 *PublicreportReport) InsertReportLogs(ctx context.Context, exec bob.Executor, related ...*PublicreportReportLogSetter) error { + if len(related) == 0 { + return nil + } + + var err error + + publicreportReportLogs1, err := insertPublicreportReportReportLogs0(ctx, exec, related, publicreportReport0) + if err != nil { + return err + } + + publicreportReport0.R.ReportLogs = append(publicreportReport0.R.ReportLogs, publicreportReportLogs1...) + + for _, rel := range publicreportReportLogs1 { + rel.R.Report = publicreportReport0 + } + return nil +} + +func (publicreportReport0 *PublicreportReport) AttachReportLogs(ctx context.Context, exec bob.Executor, related ...*PublicreportReportLog) error { + if len(related) == 0 { + return nil + } + + var err error + publicreportReportLogs1 := PublicreportReportLogSlice(related) + + _, err = attachPublicreportReportReportLogs0(ctx, exec, len(related), publicreportReportLogs1, publicreportReport0) + if err != nil { + return err + } + + publicreportReport0.R.ReportLogs = append(publicreportReport0.R.ReportLogs, publicreportReportLogs1...) + + for _, rel := range related { + rel.R.Report = publicreportReport0 + } + + return nil +} + func insertPublicreportReportWater0(ctx context.Context, exec bob.Executor, publicreportWater1 *PublicreportWaterSetter, publicreportReport0 *PublicreportReport) (*PublicreportWater, error) { publicreportWater1.ReportID = omit.From(publicreportReport0.ID) @@ -1916,6 +2009,20 @@ func (o *PublicreportReport) Preload(name string, retrieved any) error { } } return nil + case "ReportLogs": + rels, ok := retrieved.(PublicreportReportLogSlice) + if !ok { + return fmt.Errorf("publicreportReport cannot load %T as %q", retrieved, name) + } + + o.R.ReportLogs = rels + + for _, rel := range rels { + if rel != nil { + rel.R.Report = o + } + } + return nil case "Water": rel, ok := retrieved.(*PublicreportWater) if !ok { @@ -2034,6 +2141,7 @@ type publicreportReportThenLoader[Q orm.Loadable] struct { Organization func(...bob.Mod[*dialect.SelectQuery]) orm.Loader[Q] ReviewerUser func(...bob.Mod[*dialect.SelectQuery]) orm.Loader[Q] Images func(...bob.Mod[*dialect.SelectQuery]) orm.Loader[Q] + ReportLogs func(...bob.Mod[*dialect.SelectQuery]) orm.Loader[Q] Water func(...bob.Mod[*dialect.SelectQuery]) orm.Loader[Q] ReportTexts func(...bob.Mod[*dialect.SelectQuery]) orm.Loader[Q] } @@ -2063,6 +2171,9 @@ func buildPublicreportReportThenLoader[Q orm.Loadable]() publicreportReportThenL type ImagesLoadInterface interface { LoadImages(context.Context, bob.Executor, ...bob.Mod[*dialect.SelectQuery]) error } + type ReportLogsLoadInterface interface { + LoadReportLogs(context.Context, bob.Executor, ...bob.Mod[*dialect.SelectQuery]) error + } type WaterLoadInterface interface { LoadWater(context.Context, bob.Executor, ...bob.Mod[*dialect.SelectQuery]) error } @@ -2119,6 +2230,12 @@ func buildPublicreportReportThenLoader[Q orm.Loadable]() publicreportReportThenL return retrieved.LoadImages(ctx, exec, mods...) }, ), + ReportLogs: thenLoadBuilder[Q]( + "ReportLogs", + func(ctx context.Context, exec bob.Executor, retrieved ReportLogsLoadInterface, mods ...bob.Mod[*dialect.SelectQuery]) error { + return retrieved.LoadReportLogs(ctx, exec, mods...) + }, + ), Water: thenLoadBuilder[Q]( "Water", func(ctx context.Context, exec bob.Executor, retrieved WaterLoadInterface, mods ...bob.Mod[*dialect.SelectQuery]) error { @@ -2615,6 +2732,67 @@ func (os PublicreportReportSlice) LoadImages(ctx context.Context, exec bob.Execu return nil } +// LoadReportLogs loads the publicreportReport's ReportLogs into the .R struct +func (o *PublicreportReport) LoadReportLogs(ctx context.Context, exec bob.Executor, mods ...bob.Mod[*dialect.SelectQuery]) error { + if o == nil { + return nil + } + + // Reset the relationship + o.R.ReportLogs = nil + + related, err := o.ReportLogs(mods...).All(ctx, exec) + if err != nil { + return err + } + + for _, rel := range related { + rel.R.Report = o + } + + o.R.ReportLogs = related + return nil +} + +// LoadReportLogs loads the publicreportReport's ReportLogs into the .R struct +func (os PublicreportReportSlice) LoadReportLogs(ctx context.Context, exec bob.Executor, mods ...bob.Mod[*dialect.SelectQuery]) error { + if len(os) == 0 { + return nil + } + + publicreportReportLogs, err := os.ReportLogs(mods...).All(ctx, exec) + if err != nil { + return err + } + + for _, o := range os { + if o == nil { + continue + } + + o.R.ReportLogs = nil + } + + for _, o := range os { + if o == nil { + continue + } + + for _, rel := range publicreportReportLogs { + + if !(o.ID == rel.ReportID) { + continue + } + + rel.R.Report = o + + o.R.ReportLogs = append(o.R.ReportLogs, rel) + } + } + + return nil +} + // LoadWater loads the publicreportReport's Water into the .R struct func (o *PublicreportReport) LoadWater(ctx context.Context, exec bob.Executor, mods ...bob.Mod[*dialect.SelectQuery]) error { if o == nil { diff --git a/db/models/publicreport.report_log.bob.go b/db/models/publicreport.report_log.bob.go new file mode 100644 index 00000000..ef8ba28e --- /dev/null +++ b/db/models/publicreport.report_log.bob.go @@ -0,0 +1,1193 @@ +// Code generated by BobGen psql v0.42.5. DO NOT EDIT. +// This file is meant to be re-generated in place and/or deleted at any time. + +package models + +import ( + "context" + "fmt" + "io" + "time" + + "github.com/Gleipnir-Technology/bob" + "github.com/Gleipnir-Technology/bob/dialect/psql" + "github.com/Gleipnir-Technology/bob/dialect/psql/dialect" + "github.com/Gleipnir-Technology/bob/dialect/psql/dm" + "github.com/Gleipnir-Technology/bob/dialect/psql/sm" + "github.com/Gleipnir-Technology/bob/dialect/psql/um" + "github.com/Gleipnir-Technology/bob/expr" + "github.com/Gleipnir-Technology/bob/orm" + "github.com/Gleipnir-Technology/bob/types/pgtypes" + enums "github.com/Gleipnir-Technology/nidus-sync/db/enums" + "github.com/aarondl/opt/null" + "github.com/aarondl/opt/omit" + "github.com/aarondl/opt/omitnull" +) + +// PublicreportReportLog is an object representing the database table. +type PublicreportReportLog struct { + Created time.Time `db:"created" ` + EmailLogID null.Val[int32] `db:"email_log_id" ` + ID int32 `db:"id,pk" ` + ReportID int32 `db:"report_id" ` + TextLogID null.Val[int32] `db:"text_log_id" ` + Type enums.PublicreportReportlogtype `db:"type_" ` + UserID null.Val[int32] `db:"user_id" ` + + R publicreportReportLogR `db:"-" ` +} + +// PublicreportReportLogSlice is an alias for a slice of pointers to PublicreportReportLog. +// This should almost always be used instead of []*PublicreportReportLog. +type PublicreportReportLogSlice []*PublicreportReportLog + +// PublicreportReportLogs contains methods to work with the report_log table +var PublicreportReportLogs = psql.NewTablex[*PublicreportReportLog, PublicreportReportLogSlice, *PublicreportReportLogSetter]("publicreport", "report_log", buildPublicreportReportLogColumns("publicreport.report_log")) + +// PublicreportReportLogsQuery is a query on the report_log table +type PublicreportReportLogsQuery = *psql.ViewQuery[*PublicreportReportLog, PublicreportReportLogSlice] + +// publicreportReportLogR is where relationships are stored. +type publicreportReportLogR struct { + EmailLog *CommsEmailLog // publicreport.report_log.report_log_email_log_id_fkey + Report *PublicreportReport // publicreport.report_log.report_log_report_id_fkey + TextLog *CommsTextLog // publicreport.report_log.report_log_text_log_id_fkey + UserUser *User // publicreport.report_log.report_log_user_id_fkey +} + +func buildPublicreportReportLogColumns(alias string) publicreportReportLogColumns { + return publicreportReportLogColumns{ + ColumnsExpr: expr.NewColumnsExpr( + "created", "email_log_id", "id", "report_id", "text_log_id", "type_", "user_id", + ).WithParent("publicreport.report_log"), + tableAlias: alias, + Created: psql.Quote(alias, "created"), + EmailLogID: psql.Quote(alias, "email_log_id"), + ID: psql.Quote(alias, "id"), + ReportID: psql.Quote(alias, "report_id"), + TextLogID: psql.Quote(alias, "text_log_id"), + Type: psql.Quote(alias, "type_"), + UserID: psql.Quote(alias, "user_id"), + } +} + +type publicreportReportLogColumns struct { + expr.ColumnsExpr + tableAlias string + Created psql.Expression + EmailLogID psql.Expression + ID psql.Expression + ReportID psql.Expression + TextLogID psql.Expression + Type psql.Expression + UserID psql.Expression +} + +func (c publicreportReportLogColumns) Alias() string { + return c.tableAlias +} + +func (publicreportReportLogColumns) AliasedAs(alias string) publicreportReportLogColumns { + return buildPublicreportReportLogColumns(alias) +} + +// PublicreportReportLogSetter is used for insert/upsert/update operations +// All values are optional, and do not have to be set +// Generated columns are not included +type PublicreportReportLogSetter struct { + Created omit.Val[time.Time] `db:"created" ` + EmailLogID omitnull.Val[int32] `db:"email_log_id" ` + ID omit.Val[int32] `db:"id,pk" ` + ReportID omit.Val[int32] `db:"report_id" ` + TextLogID omitnull.Val[int32] `db:"text_log_id" ` + Type omit.Val[enums.PublicreportReportlogtype] `db:"type_" ` + UserID omitnull.Val[int32] `db:"user_id" ` +} + +func (s PublicreportReportLogSetter) SetColumns() []string { + vals := make([]string, 0, 7) + if s.Created.IsValue() { + vals = append(vals, "created") + } + if !s.EmailLogID.IsUnset() { + vals = append(vals, "email_log_id") + } + if s.ID.IsValue() { + vals = append(vals, "id") + } + if s.ReportID.IsValue() { + vals = append(vals, "report_id") + } + if !s.TextLogID.IsUnset() { + vals = append(vals, "text_log_id") + } + if s.Type.IsValue() { + vals = append(vals, "type_") + } + if !s.UserID.IsUnset() { + vals = append(vals, "user_id") + } + return vals +} + +func (s PublicreportReportLogSetter) Overwrite(t *PublicreportReportLog) { + if s.Created.IsValue() { + t.Created = s.Created.MustGet() + } + if !s.EmailLogID.IsUnset() { + t.EmailLogID = s.EmailLogID.MustGetNull() + } + if s.ID.IsValue() { + t.ID = s.ID.MustGet() + } + if s.ReportID.IsValue() { + t.ReportID = s.ReportID.MustGet() + } + if !s.TextLogID.IsUnset() { + t.TextLogID = s.TextLogID.MustGetNull() + } + if s.Type.IsValue() { + t.Type = s.Type.MustGet() + } + if !s.UserID.IsUnset() { + t.UserID = s.UserID.MustGetNull() + } +} + +func (s *PublicreportReportLogSetter) Apply(q *dialect.InsertQuery) { + q.AppendHooks(func(ctx context.Context, exec bob.Executor) (context.Context, error) { + return PublicreportReportLogs.BeforeInsertHooks.RunHooks(ctx, exec, s) + }) + + q.AppendValues(bob.ExpressionFunc(func(ctx context.Context, w io.StringWriter, d bob.Dialect, start int) ([]any, error) { + vals := make([]bob.Expression, 7) + if s.Created.IsValue() { + vals[0] = psql.Arg(s.Created.MustGet()) + } else { + vals[0] = psql.Raw("DEFAULT") + } + + if !s.EmailLogID.IsUnset() { + vals[1] = psql.Arg(s.EmailLogID.MustGetNull()) + } else { + vals[1] = psql.Raw("DEFAULT") + } + + if s.ID.IsValue() { + vals[2] = psql.Arg(s.ID.MustGet()) + } else { + vals[2] = psql.Raw("DEFAULT") + } + + if s.ReportID.IsValue() { + vals[3] = psql.Arg(s.ReportID.MustGet()) + } else { + vals[3] = psql.Raw("DEFAULT") + } + + if !s.TextLogID.IsUnset() { + vals[4] = psql.Arg(s.TextLogID.MustGetNull()) + } else { + vals[4] = psql.Raw("DEFAULT") + } + + if s.Type.IsValue() { + vals[5] = psql.Arg(s.Type.MustGet()) + } else { + vals[5] = psql.Raw("DEFAULT") + } + + if !s.UserID.IsUnset() { + vals[6] = psql.Arg(s.UserID.MustGetNull()) + } else { + vals[6] = psql.Raw("DEFAULT") + } + + return bob.ExpressSlice(ctx, w, d, start, vals, "", ", ", "") + })) +} + +func (s PublicreportReportLogSetter) UpdateMod() bob.Mod[*dialect.UpdateQuery] { + return um.Set(s.Expressions()...) +} + +func (s PublicreportReportLogSetter) Expressions(prefix ...string) []bob.Expression { + exprs := make([]bob.Expression, 0, 7) + + if s.Created.IsValue() { + exprs = append(exprs, expr.Join{Sep: " = ", Exprs: []bob.Expression{ + psql.Quote(append(prefix, "created")...), + psql.Arg(s.Created), + }}) + } + + if !s.EmailLogID.IsUnset() { + exprs = append(exprs, expr.Join{Sep: " = ", Exprs: []bob.Expression{ + psql.Quote(append(prefix, "email_log_id")...), + psql.Arg(s.EmailLogID), + }}) + } + + if s.ID.IsValue() { + exprs = append(exprs, expr.Join{Sep: " = ", Exprs: []bob.Expression{ + psql.Quote(append(prefix, "id")...), + psql.Arg(s.ID), + }}) + } + + if s.ReportID.IsValue() { + exprs = append(exprs, expr.Join{Sep: " = ", Exprs: []bob.Expression{ + psql.Quote(append(prefix, "report_id")...), + psql.Arg(s.ReportID), + }}) + } + + if !s.TextLogID.IsUnset() { + exprs = append(exprs, expr.Join{Sep: " = ", Exprs: []bob.Expression{ + psql.Quote(append(prefix, "text_log_id")...), + psql.Arg(s.TextLogID), + }}) + } + + if s.Type.IsValue() { + exprs = append(exprs, expr.Join{Sep: " = ", Exprs: []bob.Expression{ + psql.Quote(append(prefix, "type_")...), + psql.Arg(s.Type), + }}) + } + + if !s.UserID.IsUnset() { + exprs = append(exprs, expr.Join{Sep: " = ", Exprs: []bob.Expression{ + psql.Quote(append(prefix, "user_id")...), + psql.Arg(s.UserID), + }}) + } + + return exprs +} + +// FindPublicreportReportLog retrieves a single record by primary key +// If cols is empty Find will return all columns. +func FindPublicreportReportLog(ctx context.Context, exec bob.Executor, IDPK int32, cols ...string) (*PublicreportReportLog, error) { + if len(cols) == 0 { + return PublicreportReportLogs.Query( + sm.Where(PublicreportReportLogs.Columns.ID.EQ(psql.Arg(IDPK))), + ).One(ctx, exec) + } + + return PublicreportReportLogs.Query( + sm.Where(PublicreportReportLogs.Columns.ID.EQ(psql.Arg(IDPK))), + sm.Columns(PublicreportReportLogs.Columns.Only(cols...)), + ).One(ctx, exec) +} + +// PublicreportReportLogExists checks the presence of a single record by primary key +func PublicreportReportLogExists(ctx context.Context, exec bob.Executor, IDPK int32) (bool, error) { + return PublicreportReportLogs.Query( + sm.Where(PublicreportReportLogs.Columns.ID.EQ(psql.Arg(IDPK))), + ).Exists(ctx, exec) +} + +// AfterQueryHook is called after PublicreportReportLog is retrieved from the database +func (o *PublicreportReportLog) AfterQueryHook(ctx context.Context, exec bob.Executor, queryType bob.QueryType) error { + var err error + + switch queryType { + case bob.QueryTypeSelect: + ctx, err = PublicreportReportLogs.AfterSelectHooks.RunHooks(ctx, exec, PublicreportReportLogSlice{o}) + case bob.QueryTypeInsert: + ctx, err = PublicreportReportLogs.AfterInsertHooks.RunHooks(ctx, exec, PublicreportReportLogSlice{o}) + case bob.QueryTypeUpdate: + ctx, err = PublicreportReportLogs.AfterUpdateHooks.RunHooks(ctx, exec, PublicreportReportLogSlice{o}) + case bob.QueryTypeDelete: + ctx, err = PublicreportReportLogs.AfterDeleteHooks.RunHooks(ctx, exec, PublicreportReportLogSlice{o}) + } + + return err +} + +// primaryKeyVals returns the primary key values of the PublicreportReportLog +func (o *PublicreportReportLog) primaryKeyVals() bob.Expression { + return psql.Arg(o.ID) +} + +func (o *PublicreportReportLog) pkEQ() dialect.Expression { + return psql.Quote("publicreport.report_log", "id").EQ(bob.ExpressionFunc(func(ctx context.Context, w io.StringWriter, d bob.Dialect, start int) ([]any, error) { + return o.primaryKeyVals().WriteSQL(ctx, w, d, start) + })) +} + +// Update uses an executor to update the PublicreportReportLog +func (o *PublicreportReportLog) Update(ctx context.Context, exec bob.Executor, s *PublicreportReportLogSetter) error { + v, err := PublicreportReportLogs.Update(s.UpdateMod(), um.Where(o.pkEQ())).One(ctx, exec) + if err != nil { + return err + } + + o.R = v.R + *o = *v + + return nil +} + +// Delete deletes a single PublicreportReportLog record with an executor +func (o *PublicreportReportLog) Delete(ctx context.Context, exec bob.Executor) error { + _, err := PublicreportReportLogs.Delete(dm.Where(o.pkEQ())).Exec(ctx, exec) + return err +} + +// Reload refreshes the PublicreportReportLog using the executor +func (o *PublicreportReportLog) Reload(ctx context.Context, exec bob.Executor) error { + o2, err := PublicreportReportLogs.Query( + sm.Where(PublicreportReportLogs.Columns.ID.EQ(psql.Arg(o.ID))), + ).One(ctx, exec) + if err != nil { + return err + } + o2.R = o.R + *o = *o2 + + return nil +} + +// AfterQueryHook is called after PublicreportReportLogSlice is retrieved from the database +func (o PublicreportReportLogSlice) AfterQueryHook(ctx context.Context, exec bob.Executor, queryType bob.QueryType) error { + var err error + + switch queryType { + case bob.QueryTypeSelect: + ctx, err = PublicreportReportLogs.AfterSelectHooks.RunHooks(ctx, exec, o) + case bob.QueryTypeInsert: + ctx, err = PublicreportReportLogs.AfterInsertHooks.RunHooks(ctx, exec, o) + case bob.QueryTypeUpdate: + ctx, err = PublicreportReportLogs.AfterUpdateHooks.RunHooks(ctx, exec, o) + case bob.QueryTypeDelete: + ctx, err = PublicreportReportLogs.AfterDeleteHooks.RunHooks(ctx, exec, o) + } + + return err +} + +func (o PublicreportReportLogSlice) pkIN() dialect.Expression { + if len(o) == 0 { + return psql.Raw("NULL") + } + + return psql.Quote("publicreport.report_log", "id").In(bob.ExpressionFunc(func(ctx context.Context, w io.StringWriter, d bob.Dialect, start int) ([]any, error) { + pkPairs := make([]bob.Expression, len(o)) + for i, row := range o { + pkPairs[i] = row.primaryKeyVals() + } + return bob.ExpressSlice(ctx, w, d, start, pkPairs, "", ", ", "") + })) +} + +// copyMatchingRows finds models in the given slice that have the same primary key +// then it first copies the existing relationships from the old model to the new model +// and then replaces the old model in the slice with the new model +func (o PublicreportReportLogSlice) copyMatchingRows(from ...*PublicreportReportLog) { + for i, old := range o { + for _, new := range from { + if new.ID != old.ID { + continue + } + new.R = old.R + o[i] = new + break + } + } +} + +// UpdateMod modifies an update query with "WHERE primary_key IN (o...)" +func (o PublicreportReportLogSlice) UpdateMod() bob.Mod[*dialect.UpdateQuery] { + return bob.ModFunc[*dialect.UpdateQuery](func(q *dialect.UpdateQuery) { + q.AppendHooks(func(ctx context.Context, exec bob.Executor) (context.Context, error) { + return PublicreportReportLogs.BeforeUpdateHooks.RunHooks(ctx, exec, o) + }) + + q.AppendLoader(bob.LoaderFunc(func(ctx context.Context, exec bob.Executor, retrieved any) error { + var err error + switch retrieved := retrieved.(type) { + case *PublicreportReportLog: + o.copyMatchingRows(retrieved) + case []*PublicreportReportLog: + o.copyMatchingRows(retrieved...) + case PublicreportReportLogSlice: + o.copyMatchingRows(retrieved...) + default: + // If the retrieved value is not a PublicreportReportLog or a slice of PublicreportReportLog + // then run the AfterUpdateHooks on the slice + _, err = PublicreportReportLogs.AfterUpdateHooks.RunHooks(ctx, exec, o) + } + + return err + })) + + q.AppendWhere(o.pkIN()) + }) +} + +// DeleteMod modifies an delete query with "WHERE primary_key IN (o...)" +func (o PublicreportReportLogSlice) DeleteMod() bob.Mod[*dialect.DeleteQuery] { + return bob.ModFunc[*dialect.DeleteQuery](func(q *dialect.DeleteQuery) { + q.AppendHooks(func(ctx context.Context, exec bob.Executor) (context.Context, error) { + return PublicreportReportLogs.BeforeDeleteHooks.RunHooks(ctx, exec, o) + }) + + q.AppendLoader(bob.LoaderFunc(func(ctx context.Context, exec bob.Executor, retrieved any) error { + var err error + switch retrieved := retrieved.(type) { + case *PublicreportReportLog: + o.copyMatchingRows(retrieved) + case []*PublicreportReportLog: + o.copyMatchingRows(retrieved...) + case PublicreportReportLogSlice: + o.copyMatchingRows(retrieved...) + default: + // If the retrieved value is not a PublicreportReportLog or a slice of PublicreportReportLog + // then run the AfterDeleteHooks on the slice + _, err = PublicreportReportLogs.AfterDeleteHooks.RunHooks(ctx, exec, o) + } + + return err + })) + + q.AppendWhere(o.pkIN()) + }) +} + +func (o PublicreportReportLogSlice) UpdateAll(ctx context.Context, exec bob.Executor, vals PublicreportReportLogSetter) error { + if len(o) == 0 { + return nil + } + + _, err := PublicreportReportLogs.Update(vals.UpdateMod(), o.UpdateMod()).All(ctx, exec) + return err +} + +func (o PublicreportReportLogSlice) DeleteAll(ctx context.Context, exec bob.Executor) error { + if len(o) == 0 { + return nil + } + + _, err := PublicreportReportLogs.Delete(o.DeleteMod()).Exec(ctx, exec) + return err +} + +func (o PublicreportReportLogSlice) ReloadAll(ctx context.Context, exec bob.Executor) error { + if len(o) == 0 { + return nil + } + + o2, err := PublicreportReportLogs.Query(sm.Where(o.pkIN())).All(ctx, exec) + if err != nil { + return err + } + + o.copyMatchingRows(o2...) + + return nil +} + +// EmailLog starts a query for related objects on comms.email_log +func (o *PublicreportReportLog) EmailLog(mods ...bob.Mod[*dialect.SelectQuery]) CommsEmailLogsQuery { + return CommsEmailLogs.Query(append(mods, + sm.Where(CommsEmailLogs.Columns.ID.EQ(psql.Arg(o.EmailLogID))), + )...) +} + +func (os PublicreportReportLogSlice) EmailLog(mods ...bob.Mod[*dialect.SelectQuery]) CommsEmailLogsQuery { + pkEmailLogID := make(pgtypes.Array[null.Val[int32]], 0, len(os)) + for _, o := range os { + if o == nil { + continue + } + pkEmailLogID = append(pkEmailLogID, o.EmailLogID) + } + PKArgExpr := psql.Select(sm.Columns( + psql.F("unnest", psql.Cast(psql.Arg(pkEmailLogID), "integer[]")), + )) + + return CommsEmailLogs.Query(append(mods, + sm.Where(psql.Group(CommsEmailLogs.Columns.ID).OP("IN", PKArgExpr)), + )...) +} + +// Report starts a query for related objects on publicreport.report +func (o *PublicreportReportLog) Report(mods ...bob.Mod[*dialect.SelectQuery]) PublicreportReportsQuery { + return PublicreportReports.Query(append(mods, + sm.Where(PublicreportReports.Columns.ID.EQ(psql.Arg(o.ReportID))), + )...) +} + +func (os PublicreportReportLogSlice) Report(mods ...bob.Mod[*dialect.SelectQuery]) PublicreportReportsQuery { + pkReportID := make(pgtypes.Array[int32], 0, len(os)) + for _, o := range os { + if o == nil { + continue + } + pkReportID = append(pkReportID, o.ReportID) + } + PKArgExpr := psql.Select(sm.Columns( + psql.F("unnest", psql.Cast(psql.Arg(pkReportID), "integer[]")), + )) + + return PublicreportReports.Query(append(mods, + sm.Where(psql.Group(PublicreportReports.Columns.ID).OP("IN", PKArgExpr)), + )...) +} + +// TextLog starts a query for related objects on comms.text_log +func (o *PublicreportReportLog) TextLog(mods ...bob.Mod[*dialect.SelectQuery]) CommsTextLogsQuery { + return CommsTextLogs.Query(append(mods, + sm.Where(CommsTextLogs.Columns.ID.EQ(psql.Arg(o.TextLogID))), + )...) +} + +func (os PublicreportReportLogSlice) TextLog(mods ...bob.Mod[*dialect.SelectQuery]) CommsTextLogsQuery { + pkTextLogID := make(pgtypes.Array[null.Val[int32]], 0, len(os)) + for _, o := range os { + if o == nil { + continue + } + pkTextLogID = append(pkTextLogID, o.TextLogID) + } + PKArgExpr := psql.Select(sm.Columns( + psql.F("unnest", psql.Cast(psql.Arg(pkTextLogID), "integer[]")), + )) + + return CommsTextLogs.Query(append(mods, + sm.Where(psql.Group(CommsTextLogs.Columns.ID).OP("IN", PKArgExpr)), + )...) +} + +// UserUser starts a query for related objects on user_ +func (o *PublicreportReportLog) UserUser(mods ...bob.Mod[*dialect.SelectQuery]) UsersQuery { + return Users.Query(append(mods, + sm.Where(Users.Columns.ID.EQ(psql.Arg(o.UserID))), + )...) +} + +func (os PublicreportReportLogSlice) UserUser(mods ...bob.Mod[*dialect.SelectQuery]) UsersQuery { + pkUserID := make(pgtypes.Array[null.Val[int32]], 0, len(os)) + for _, o := range os { + if o == nil { + continue + } + pkUserID = append(pkUserID, o.UserID) + } + PKArgExpr := psql.Select(sm.Columns( + psql.F("unnest", psql.Cast(psql.Arg(pkUserID), "integer[]")), + )) + + return Users.Query(append(mods, + sm.Where(psql.Group(Users.Columns.ID).OP("IN", PKArgExpr)), + )...) +} + +func attachPublicreportReportLogEmailLog0(ctx context.Context, exec bob.Executor, count int, publicreportReportLog0 *PublicreportReportLog, commsEmailLog1 *CommsEmailLog) (*PublicreportReportLog, error) { + setter := &PublicreportReportLogSetter{ + EmailLogID: omitnull.From(commsEmailLog1.ID), + } + + err := publicreportReportLog0.Update(ctx, exec, setter) + if err != nil { + return nil, fmt.Errorf("attachPublicreportReportLogEmailLog0: %w", err) + } + + return publicreportReportLog0, nil +} + +func (publicreportReportLog0 *PublicreportReportLog) InsertEmailLog(ctx context.Context, exec bob.Executor, related *CommsEmailLogSetter) error { + var err error + + commsEmailLog1, err := CommsEmailLogs.Insert(related).One(ctx, exec) + if err != nil { + return fmt.Errorf("inserting related objects: %w", err) + } + + _, err = attachPublicreportReportLogEmailLog0(ctx, exec, 1, publicreportReportLog0, commsEmailLog1) + if err != nil { + return err + } + + publicreportReportLog0.R.EmailLog = commsEmailLog1 + + commsEmailLog1.R.ReportLogs = append(commsEmailLog1.R.ReportLogs, publicreportReportLog0) + + return nil +} + +func (publicreportReportLog0 *PublicreportReportLog) AttachEmailLog(ctx context.Context, exec bob.Executor, commsEmailLog1 *CommsEmailLog) error { + var err error + + _, err = attachPublicreportReportLogEmailLog0(ctx, exec, 1, publicreportReportLog0, commsEmailLog1) + if err != nil { + return err + } + + publicreportReportLog0.R.EmailLog = commsEmailLog1 + + commsEmailLog1.R.ReportLogs = append(commsEmailLog1.R.ReportLogs, publicreportReportLog0) + + return nil +} + +func attachPublicreportReportLogReport0(ctx context.Context, exec bob.Executor, count int, publicreportReportLog0 *PublicreportReportLog, publicreportReport1 *PublicreportReport) (*PublicreportReportLog, error) { + setter := &PublicreportReportLogSetter{ + ReportID: omit.From(publicreportReport1.ID), + } + + err := publicreportReportLog0.Update(ctx, exec, setter) + if err != nil { + return nil, fmt.Errorf("attachPublicreportReportLogReport0: %w", err) + } + + return publicreportReportLog0, nil +} + +func (publicreportReportLog0 *PublicreportReportLog) InsertReport(ctx context.Context, exec bob.Executor, related *PublicreportReportSetter) error { + var err error + + publicreportReport1, err := PublicreportReports.Insert(related).One(ctx, exec) + if err != nil { + return fmt.Errorf("inserting related objects: %w", err) + } + + _, err = attachPublicreportReportLogReport0(ctx, exec, 1, publicreportReportLog0, publicreportReport1) + if err != nil { + return err + } + + publicreportReportLog0.R.Report = publicreportReport1 + + publicreportReport1.R.ReportLogs = append(publicreportReport1.R.ReportLogs, publicreportReportLog0) + + return nil +} + +func (publicreportReportLog0 *PublicreportReportLog) AttachReport(ctx context.Context, exec bob.Executor, publicreportReport1 *PublicreportReport) error { + var err error + + _, err = attachPublicreportReportLogReport0(ctx, exec, 1, publicreportReportLog0, publicreportReport1) + if err != nil { + return err + } + + publicreportReportLog0.R.Report = publicreportReport1 + + publicreportReport1.R.ReportLogs = append(publicreportReport1.R.ReportLogs, publicreportReportLog0) + + return nil +} + +func attachPublicreportReportLogTextLog0(ctx context.Context, exec bob.Executor, count int, publicreportReportLog0 *PublicreportReportLog, commsTextLog1 *CommsTextLog) (*PublicreportReportLog, error) { + setter := &PublicreportReportLogSetter{ + TextLogID: omitnull.From(commsTextLog1.ID), + } + + err := publicreportReportLog0.Update(ctx, exec, setter) + if err != nil { + return nil, fmt.Errorf("attachPublicreportReportLogTextLog0: %w", err) + } + + return publicreportReportLog0, nil +} + +func (publicreportReportLog0 *PublicreportReportLog) InsertTextLog(ctx context.Context, exec bob.Executor, related *CommsTextLogSetter) error { + var err error + + commsTextLog1, err := CommsTextLogs.Insert(related).One(ctx, exec) + if err != nil { + return fmt.Errorf("inserting related objects: %w", err) + } + + _, err = attachPublicreportReportLogTextLog0(ctx, exec, 1, publicreportReportLog0, commsTextLog1) + if err != nil { + return err + } + + publicreportReportLog0.R.TextLog = commsTextLog1 + + commsTextLog1.R.ReportLogs = append(commsTextLog1.R.ReportLogs, publicreportReportLog0) + + return nil +} + +func (publicreportReportLog0 *PublicreportReportLog) AttachTextLog(ctx context.Context, exec bob.Executor, commsTextLog1 *CommsTextLog) error { + var err error + + _, err = attachPublicreportReportLogTextLog0(ctx, exec, 1, publicreportReportLog0, commsTextLog1) + if err != nil { + return err + } + + publicreportReportLog0.R.TextLog = commsTextLog1 + + commsTextLog1.R.ReportLogs = append(commsTextLog1.R.ReportLogs, publicreportReportLog0) + + return nil +} + +func attachPublicreportReportLogUserUser0(ctx context.Context, exec bob.Executor, count int, publicreportReportLog0 *PublicreportReportLog, user1 *User) (*PublicreportReportLog, error) { + setter := &PublicreportReportLogSetter{ + UserID: omitnull.From(user1.ID), + } + + err := publicreportReportLog0.Update(ctx, exec, setter) + if err != nil { + return nil, fmt.Errorf("attachPublicreportReportLogUserUser0: %w", err) + } + + return publicreportReportLog0, nil +} + +func (publicreportReportLog0 *PublicreportReportLog) InsertUserUser(ctx context.Context, exec bob.Executor, related *UserSetter) error { + var err error + + user1, err := Users.Insert(related).One(ctx, exec) + if err != nil { + return fmt.Errorf("inserting related objects: %w", err) + } + + _, err = attachPublicreportReportLogUserUser0(ctx, exec, 1, publicreportReportLog0, user1) + if err != nil { + return err + } + + publicreportReportLog0.R.UserUser = user1 + + user1.R.UserReportLogs = append(user1.R.UserReportLogs, publicreportReportLog0) + + return nil +} + +func (publicreportReportLog0 *PublicreportReportLog) AttachUserUser(ctx context.Context, exec bob.Executor, user1 *User) error { + var err error + + _, err = attachPublicreportReportLogUserUser0(ctx, exec, 1, publicreportReportLog0, user1) + if err != nil { + return err + } + + publicreportReportLog0.R.UserUser = user1 + + user1.R.UserReportLogs = append(user1.R.UserReportLogs, publicreportReportLog0) + + return nil +} + +type publicreportReportLogWhere[Q psql.Filterable] struct { + Created psql.WhereMod[Q, time.Time] + EmailLogID psql.WhereNullMod[Q, int32] + ID psql.WhereMod[Q, int32] + ReportID psql.WhereMod[Q, int32] + TextLogID psql.WhereNullMod[Q, int32] + Type psql.WhereMod[Q, enums.PublicreportReportlogtype] + UserID psql.WhereNullMod[Q, int32] +} + +func (publicreportReportLogWhere[Q]) AliasedAs(alias string) publicreportReportLogWhere[Q] { + return buildPublicreportReportLogWhere[Q](buildPublicreportReportLogColumns(alias)) +} + +func buildPublicreportReportLogWhere[Q psql.Filterable](cols publicreportReportLogColumns) publicreportReportLogWhere[Q] { + return publicreportReportLogWhere[Q]{ + Created: psql.Where[Q, time.Time](cols.Created), + EmailLogID: psql.WhereNull[Q, int32](cols.EmailLogID), + ID: psql.Where[Q, int32](cols.ID), + ReportID: psql.Where[Q, int32](cols.ReportID), + TextLogID: psql.WhereNull[Q, int32](cols.TextLogID), + Type: psql.Where[Q, enums.PublicreportReportlogtype](cols.Type), + UserID: psql.WhereNull[Q, int32](cols.UserID), + } +} + +func (o *PublicreportReportLog) Preload(name string, retrieved any) error { + if o == nil { + return nil + } + + switch name { + case "EmailLog": + rel, ok := retrieved.(*CommsEmailLog) + if !ok { + return fmt.Errorf("publicreportReportLog cannot load %T as %q", retrieved, name) + } + + o.R.EmailLog = rel + + if rel != nil { + rel.R.ReportLogs = PublicreportReportLogSlice{o} + } + return nil + case "Report": + rel, ok := retrieved.(*PublicreportReport) + if !ok { + return fmt.Errorf("publicreportReportLog cannot load %T as %q", retrieved, name) + } + + o.R.Report = rel + + if rel != nil { + rel.R.ReportLogs = PublicreportReportLogSlice{o} + } + return nil + case "TextLog": + rel, ok := retrieved.(*CommsTextLog) + if !ok { + return fmt.Errorf("publicreportReportLog cannot load %T as %q", retrieved, name) + } + + o.R.TextLog = rel + + if rel != nil { + rel.R.ReportLogs = PublicreportReportLogSlice{o} + } + return nil + case "UserUser": + rel, ok := retrieved.(*User) + if !ok { + return fmt.Errorf("publicreportReportLog cannot load %T as %q", retrieved, name) + } + + o.R.UserUser = rel + + if rel != nil { + rel.R.UserReportLogs = PublicreportReportLogSlice{o} + } + return nil + default: + return fmt.Errorf("publicreportReportLog has no relationship %q", name) + } +} + +type publicreportReportLogPreloader struct { + EmailLog func(...psql.PreloadOption) psql.Preloader + Report func(...psql.PreloadOption) psql.Preloader + TextLog func(...psql.PreloadOption) psql.Preloader + UserUser func(...psql.PreloadOption) psql.Preloader +} + +func buildPublicreportReportLogPreloader() publicreportReportLogPreloader { + return publicreportReportLogPreloader{ + EmailLog: func(opts ...psql.PreloadOption) psql.Preloader { + return psql.Preload[*CommsEmailLog, CommsEmailLogSlice](psql.PreloadRel{ + Name: "EmailLog", + Sides: []psql.PreloadSide{ + { + From: PublicreportReportLogs, + To: CommsEmailLogs, + FromColumns: []string{"email_log_id"}, + ToColumns: []string{"id"}, + }, + }, + }, CommsEmailLogs.Columns.Names(), opts...) + }, + Report: func(opts ...psql.PreloadOption) psql.Preloader { + return psql.Preload[*PublicreportReport, PublicreportReportSlice](psql.PreloadRel{ + Name: "Report", + Sides: []psql.PreloadSide{ + { + From: PublicreportReportLogs, + To: PublicreportReports, + FromColumns: []string{"report_id"}, + ToColumns: []string{"id"}, + }, + }, + }, PublicreportReports.Columns.Names(), opts...) + }, + TextLog: func(opts ...psql.PreloadOption) psql.Preloader { + return psql.Preload[*CommsTextLog, CommsTextLogSlice](psql.PreloadRel{ + Name: "TextLog", + Sides: []psql.PreloadSide{ + { + From: PublicreportReportLogs, + To: CommsTextLogs, + FromColumns: []string{"text_log_id"}, + ToColumns: []string{"id"}, + }, + }, + }, CommsTextLogs.Columns.Names(), opts...) + }, + UserUser: func(opts ...psql.PreloadOption) psql.Preloader { + return psql.Preload[*User, UserSlice](psql.PreloadRel{ + Name: "UserUser", + Sides: []psql.PreloadSide{ + { + From: PublicreportReportLogs, + To: Users, + FromColumns: []string{"user_id"}, + ToColumns: []string{"id"}, + }, + }, + }, Users.Columns.Names(), opts...) + }, + } +} + +type publicreportReportLogThenLoader[Q orm.Loadable] struct { + EmailLog func(...bob.Mod[*dialect.SelectQuery]) orm.Loader[Q] + Report func(...bob.Mod[*dialect.SelectQuery]) orm.Loader[Q] + TextLog func(...bob.Mod[*dialect.SelectQuery]) orm.Loader[Q] + UserUser func(...bob.Mod[*dialect.SelectQuery]) orm.Loader[Q] +} + +func buildPublicreportReportLogThenLoader[Q orm.Loadable]() publicreportReportLogThenLoader[Q] { + type EmailLogLoadInterface interface { + LoadEmailLog(context.Context, bob.Executor, ...bob.Mod[*dialect.SelectQuery]) error + } + type ReportLoadInterface interface { + LoadReport(context.Context, bob.Executor, ...bob.Mod[*dialect.SelectQuery]) error + } + type TextLogLoadInterface interface { + LoadTextLog(context.Context, bob.Executor, ...bob.Mod[*dialect.SelectQuery]) error + } + type UserUserLoadInterface interface { + LoadUserUser(context.Context, bob.Executor, ...bob.Mod[*dialect.SelectQuery]) error + } + + return publicreportReportLogThenLoader[Q]{ + EmailLog: thenLoadBuilder[Q]( + "EmailLog", + func(ctx context.Context, exec bob.Executor, retrieved EmailLogLoadInterface, mods ...bob.Mod[*dialect.SelectQuery]) error { + return retrieved.LoadEmailLog(ctx, exec, mods...) + }, + ), + Report: thenLoadBuilder[Q]( + "Report", + func(ctx context.Context, exec bob.Executor, retrieved ReportLoadInterface, mods ...bob.Mod[*dialect.SelectQuery]) error { + return retrieved.LoadReport(ctx, exec, mods...) + }, + ), + TextLog: thenLoadBuilder[Q]( + "TextLog", + func(ctx context.Context, exec bob.Executor, retrieved TextLogLoadInterface, mods ...bob.Mod[*dialect.SelectQuery]) error { + return retrieved.LoadTextLog(ctx, exec, mods...) + }, + ), + UserUser: thenLoadBuilder[Q]( + "UserUser", + func(ctx context.Context, exec bob.Executor, retrieved UserUserLoadInterface, mods ...bob.Mod[*dialect.SelectQuery]) error { + return retrieved.LoadUserUser(ctx, exec, mods...) + }, + ), + } +} + +// LoadEmailLog loads the publicreportReportLog's EmailLog into the .R struct +func (o *PublicreportReportLog) LoadEmailLog(ctx context.Context, exec bob.Executor, mods ...bob.Mod[*dialect.SelectQuery]) error { + if o == nil { + return nil + } + + // Reset the relationship + o.R.EmailLog = nil + + related, err := o.EmailLog(mods...).One(ctx, exec) + if err != nil { + return err + } + + related.R.ReportLogs = PublicreportReportLogSlice{o} + + o.R.EmailLog = related + return nil +} + +// LoadEmailLog loads the publicreportReportLog's EmailLog into the .R struct +func (os PublicreportReportLogSlice) LoadEmailLog(ctx context.Context, exec bob.Executor, mods ...bob.Mod[*dialect.SelectQuery]) error { + if len(os) == 0 { + return nil + } + + commsEmailLogs, err := os.EmailLog(mods...).All(ctx, exec) + if err != nil { + return err + } + + for _, o := range os { + if o == nil { + continue + } + + for _, rel := range commsEmailLogs { + if !o.EmailLogID.IsValue() { + continue + } + + if !(o.EmailLogID.IsValue() && o.EmailLogID.MustGet() == rel.ID) { + continue + } + + rel.R.ReportLogs = append(rel.R.ReportLogs, o) + + o.R.EmailLog = rel + break + } + } + + return nil +} + +// LoadReport loads the publicreportReportLog's Report into the .R struct +func (o *PublicreportReportLog) LoadReport(ctx context.Context, exec bob.Executor, mods ...bob.Mod[*dialect.SelectQuery]) error { + if o == nil { + return nil + } + + // Reset the relationship + o.R.Report = nil + + related, err := o.Report(mods...).One(ctx, exec) + if err != nil { + return err + } + + related.R.ReportLogs = PublicreportReportLogSlice{o} + + o.R.Report = related + return nil +} + +// LoadReport loads the publicreportReportLog's Report into the .R struct +func (os PublicreportReportLogSlice) LoadReport(ctx context.Context, exec bob.Executor, mods ...bob.Mod[*dialect.SelectQuery]) error { + if len(os) == 0 { + return nil + } + + publicreportReports, err := os.Report(mods...).All(ctx, exec) + if err != nil { + return err + } + + for _, o := range os { + if o == nil { + continue + } + + for _, rel := range publicreportReports { + + if !(o.ReportID == rel.ID) { + continue + } + + rel.R.ReportLogs = append(rel.R.ReportLogs, o) + + o.R.Report = rel + break + } + } + + return nil +} + +// LoadTextLog loads the publicreportReportLog's TextLog into the .R struct +func (o *PublicreportReportLog) LoadTextLog(ctx context.Context, exec bob.Executor, mods ...bob.Mod[*dialect.SelectQuery]) error { + if o == nil { + return nil + } + + // Reset the relationship + o.R.TextLog = nil + + related, err := o.TextLog(mods...).One(ctx, exec) + if err != nil { + return err + } + + related.R.ReportLogs = PublicreportReportLogSlice{o} + + o.R.TextLog = related + return nil +} + +// LoadTextLog loads the publicreportReportLog's TextLog into the .R struct +func (os PublicreportReportLogSlice) LoadTextLog(ctx context.Context, exec bob.Executor, mods ...bob.Mod[*dialect.SelectQuery]) error { + if len(os) == 0 { + return nil + } + + commsTextLogs, err := os.TextLog(mods...).All(ctx, exec) + if err != nil { + return err + } + + for _, o := range os { + if o == nil { + continue + } + + for _, rel := range commsTextLogs { + if !o.TextLogID.IsValue() { + continue + } + + if !(o.TextLogID.IsValue() && o.TextLogID.MustGet() == rel.ID) { + continue + } + + rel.R.ReportLogs = append(rel.R.ReportLogs, o) + + o.R.TextLog = rel + break + } + } + + return nil +} + +// LoadUserUser loads the publicreportReportLog's UserUser into the .R struct +func (o *PublicreportReportLog) LoadUserUser(ctx context.Context, exec bob.Executor, mods ...bob.Mod[*dialect.SelectQuery]) error { + if o == nil { + return nil + } + + // Reset the relationship + o.R.UserUser = nil + + related, err := o.UserUser(mods...).One(ctx, exec) + if err != nil { + return err + } + + related.R.UserReportLogs = PublicreportReportLogSlice{o} + + o.R.UserUser = related + return nil +} + +// LoadUserUser loads the publicreportReportLog's UserUser into the .R struct +func (os PublicreportReportLogSlice) LoadUserUser(ctx context.Context, exec bob.Executor, mods ...bob.Mod[*dialect.SelectQuery]) error { + if len(os) == 0 { + return nil + } + + users, err := os.UserUser(mods...).All(ctx, exec) + if err != nil { + return err + } + + for _, o := range os { + if o == nil { + continue + } + + for _, rel := range users { + if !o.UserID.IsValue() { + continue + } + + if !(o.UserID.IsValue() && o.UserID.MustGet() == rel.ID) { + continue + } + + rel.R.UserReportLogs = append(rel.R.UserReportLogs, o) + + o.R.UserUser = rel + break + } + } + + return nil +} diff --git a/db/models/user_.bob.go b/db/models/user_.bob.go index eab6eda3..dbc5a2da 100644 --- a/db/models/user_.bob.go +++ b/db/models/user_.bob.go @@ -71,6 +71,7 @@ type userR struct { UserNotifications NotificationSlice // notification.notification_user_id_fkey ReviewerNuisanceOlds PublicreportNuisanceOldSlice // publicreport.nuisance_old.nuisance_reviewer_id_fkey ReviewerReports PublicreportReportSlice // publicreport.report.report_reviewer_id_fkey + UserReportLogs PublicreportReportLogSlice // publicreport.report_log.report_log_user_id_fkey ReviewerWaterOlds PublicreportWaterOldSlice // publicreport.water_old.water_reviewer_id_fkey CreatorReportTexts ReportTextSlice // report_text.report_text_creator_id_fkey CreatorResidents ResidentSlice // resident.resident_creator_fkey @@ -1032,6 +1033,30 @@ func (os UserSlice) ReviewerReports(mods ...bob.Mod[*dialect.SelectQuery]) Publi )...) } +// UserReportLogs starts a query for related objects on publicreport.report_log +func (o *User) UserReportLogs(mods ...bob.Mod[*dialect.SelectQuery]) PublicreportReportLogsQuery { + return PublicreportReportLogs.Query(append(mods, + sm.Where(PublicreportReportLogs.Columns.UserID.EQ(psql.Arg(o.ID))), + )...) +} + +func (os UserSlice) UserReportLogs(mods ...bob.Mod[*dialect.SelectQuery]) PublicreportReportLogsQuery { + 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 PublicreportReportLogs.Query(append(mods, + sm.Where(psql.Group(PublicreportReportLogs.Columns.UserID).OP("IN", PKArgExpr)), + )...) +} + // ReviewerWaterOlds starts a query for related objects on publicreport.water_old func (o *User) ReviewerWaterOlds(mods ...bob.Mod[*dialect.SelectQuery]) PublicreportWaterOldsQuery { return PublicreportWaterOlds.Query(append(mods, @@ -2336,6 +2361,74 @@ func (user0 *User) AttachReviewerReports(ctx context.Context, exec bob.Executor, return nil } +func insertUserUserReportLogs0(ctx context.Context, exec bob.Executor, publicreportReportLogs1 []*PublicreportReportLogSetter, user0 *User) (PublicreportReportLogSlice, error) { + for i := range publicreportReportLogs1 { + publicreportReportLogs1[i].UserID = omitnull.From(user0.ID) + } + + ret, err := PublicreportReportLogs.Insert(bob.ToMods(publicreportReportLogs1...)).All(ctx, exec) + if err != nil { + return ret, fmt.Errorf("insertUserUserReportLogs0: %w", err) + } + + return ret, nil +} + +func attachUserUserReportLogs0(ctx context.Context, exec bob.Executor, count int, publicreportReportLogs1 PublicreportReportLogSlice, user0 *User) (PublicreportReportLogSlice, error) { + setter := &PublicreportReportLogSetter{ + UserID: omitnull.From(user0.ID), + } + + err := publicreportReportLogs1.UpdateAll(ctx, exec, *setter) + if err != nil { + return nil, fmt.Errorf("attachUserUserReportLogs0: %w", err) + } + + return publicreportReportLogs1, nil +} + +func (user0 *User) InsertUserReportLogs(ctx context.Context, exec bob.Executor, related ...*PublicreportReportLogSetter) error { + if len(related) == 0 { + return nil + } + + var err error + + publicreportReportLogs1, err := insertUserUserReportLogs0(ctx, exec, related, user0) + if err != nil { + return err + } + + user0.R.UserReportLogs = append(user0.R.UserReportLogs, publicreportReportLogs1...) + + for _, rel := range publicreportReportLogs1 { + rel.R.UserUser = user0 + } + return nil +} + +func (user0 *User) AttachUserReportLogs(ctx context.Context, exec bob.Executor, related ...*PublicreportReportLog) error { + if len(related) == 0 { + return nil + } + + var err error + publicreportReportLogs1 := PublicreportReportLogSlice(related) + + _, err = attachUserUserReportLogs0(ctx, exec, len(related), publicreportReportLogs1, user0) + if err != nil { + return err + } + + user0.R.UserReportLogs = append(user0.R.UserReportLogs, publicreportReportLogs1...) + + for _, rel := range related { + rel.R.UserUser = user0 + } + + return nil +} + func insertUserReviewerWaterOlds0(ctx context.Context, exec bob.Executor, publicreportWaterOlds1 []*PublicreportWaterOldSetter, user0 *User) (PublicreportWaterOldSlice, error) { for i := range publicreportWaterOlds1 { publicreportWaterOlds1[i].ReviewerID = omitnull.From(user0.ID) @@ -3196,6 +3289,20 @@ func (o *User) Preload(name string, retrieved any) error { } } return nil + case "UserReportLogs": + rels, ok := retrieved.(PublicreportReportLogSlice) + if !ok { + return fmt.Errorf("user cannot load %T as %q", retrieved, name) + } + + o.R.UserReportLogs = rels + + for _, rel := range rels { + if rel != nil { + rel.R.UserUser = o + } + } + return nil case "ReviewerWaterOlds": rels, ok := retrieved.(PublicreportWaterOldSlice) if !ok { @@ -3364,6 +3471,7 @@ type userThenLoader[Q orm.Loadable] struct { UserNotifications func(...bob.Mod[*dialect.SelectQuery]) orm.Loader[Q] ReviewerNuisanceOlds func(...bob.Mod[*dialect.SelectQuery]) orm.Loader[Q] ReviewerReports func(...bob.Mod[*dialect.SelectQuery]) orm.Loader[Q] + UserReportLogs func(...bob.Mod[*dialect.SelectQuery]) orm.Loader[Q] ReviewerWaterOlds func(...bob.Mod[*dialect.SelectQuery]) orm.Loader[Q] CreatorReportTexts func(...bob.Mod[*dialect.SelectQuery]) orm.Loader[Q] CreatorResidents func(...bob.Mod[*dialect.SelectQuery]) orm.Loader[Q] @@ -3424,6 +3532,9 @@ func buildUserThenLoader[Q orm.Loadable]() userThenLoader[Q] { type ReviewerReportsLoadInterface interface { LoadReviewerReports(context.Context, bob.Executor, ...bob.Mod[*dialect.SelectQuery]) error } + type UserReportLogsLoadInterface interface { + LoadUserReportLogs(context.Context, bob.Executor, ...bob.Mod[*dialect.SelectQuery]) error + } type ReviewerWaterOldsLoadInterface interface { LoadReviewerWaterOlds(context.Context, bob.Executor, ...bob.Mod[*dialect.SelectQuery]) error } @@ -3549,6 +3660,12 @@ func buildUserThenLoader[Q orm.Loadable]() userThenLoader[Q] { return retrieved.LoadReviewerReports(ctx, exec, mods...) }, ), + UserReportLogs: thenLoadBuilder[Q]( + "UserReportLogs", + func(ctx context.Context, exec bob.Executor, retrieved UserReportLogsLoadInterface, mods ...bob.Mod[*dialect.SelectQuery]) error { + return retrieved.LoadUserReportLogs(ctx, exec, mods...) + }, + ), ReviewerWaterOlds: thenLoadBuilder[Q]( "ReviewerWaterOlds", func(ctx context.Context, exec bob.Executor, retrieved ReviewerWaterOldsLoadInterface, mods ...bob.Mod[*dialect.SelectQuery]) error { @@ -4600,6 +4717,70 @@ func (os UserSlice) LoadReviewerReports(ctx context.Context, exec bob.Executor, return nil } +// LoadUserReportLogs loads the user's UserReportLogs into the .R struct +func (o *User) LoadUserReportLogs(ctx context.Context, exec bob.Executor, mods ...bob.Mod[*dialect.SelectQuery]) error { + if o == nil { + return nil + } + + // Reset the relationship + o.R.UserReportLogs = nil + + related, err := o.UserReportLogs(mods...).All(ctx, exec) + if err != nil { + return err + } + + for _, rel := range related { + rel.R.UserUser = o + } + + o.R.UserReportLogs = related + return nil +} + +// LoadUserReportLogs loads the user's UserReportLogs into the .R struct +func (os UserSlice) LoadUserReportLogs(ctx context.Context, exec bob.Executor, mods ...bob.Mod[*dialect.SelectQuery]) error { + if len(os) == 0 { + return nil + } + + publicreportReportLogs, err := os.UserReportLogs(mods...).All(ctx, exec) + if err != nil { + return err + } + + for _, o := range os { + if o == nil { + continue + } + + o.R.UserReportLogs = nil + } + + for _, o := range os { + if o == nil { + continue + } + + for _, rel := range publicreportReportLogs { + + if !rel.UserID.IsValue() { + continue + } + if !(rel.UserID.IsValue() && o.ID == rel.UserID.MustGet()) { + continue + } + + rel.R.UserUser = o + + o.R.UserReportLogs = append(o.R.UserReportLogs, rel) + } + } + + return nil +} + // LoadReviewerWaterOlds loads the user's ReviewerWaterOlds into the .R struct func (o *User) LoadReviewerWaterOlds(ctx context.Context, exec bob.Executor, mods ...bob.Mod[*dialect.SelectQuery]) error { if o == nil { diff --git a/platform/nuisance.go b/platform/nuisance.go deleted file mode 100644 index 0d3b65ce..00000000 --- a/platform/nuisance.go +++ /dev/null @@ -1 +0,0 @@ -package platform diff --git a/platform/publicreport/log.go b/platform/publicreport/log.go new file mode 100644 index 00000000..de2608f6 --- /dev/null +++ b/platform/publicreport/log.go @@ -0,0 +1,59 @@ +package publicreport + +import ( + "context" + "fmt" + "time" + + "github.com/Gleipnir-Technology/bob" + "github.com/Gleipnir-Technology/bob/dialect/psql" + "github.com/Gleipnir-Technology/bob/dialect/psql/sm" + "github.com/Gleipnir-Technology/nidus-sync/db" + "github.com/rs/zerolog/log" + "github.com/stephenafamo/scan" +) + +type LogEntry struct { + Created time.Time `db:"created" json:"created"` + ID int32 `db:"id" json:"-"` + Message string `db:"message" json:"message"` + ReportID int32 `db:"report_id" json:"-"` + Type string `db:"type_" json:"type"` + UserID *int32 `db:"user_id" json:"user_id"` +} + +func logEntriesByReportID(ctx context.Context, report_ids []int32) (map[int32][]LogEntry, error) { + results := make(map[int32][]LogEntry, len(report_ids)) + for _, report_id := range report_ids { + results[report_id] = make([]LogEntry, 0) + } + + rows, err := bob.All(ctx, db.PGInstance.BobDB, psql.Select( + sm.Columns( + "l.created", + "l.id", + "l.report_id", + "l.type_", + "l.user_id", + ), + sm.From("publicreport.report_log").As("l"), + sm.LeftJoin("comms.email_log").As("e").OnEQ( + psql.Quote("l", "email_log_id"), + psql.Quote("e", "id"), + ), + sm.LeftJoin("comms.text_log").As("t").OnEQ( + psql.Quote("l", "text_log_id"), + psql.Quote("t", "id"), + ), + sm.Where(psql.Quote("l", "report_id").EQ(psql.Any(report_ids))), + sm.OrderBy(psql.Quote("l", "created")), + ), scan.StructMapper[LogEntry]()) + if err != nil { + return results, fmt.Errorf("query created: %w", err) + } + log.Debug().Int("len(report_ids)", len(report_ids)).Int("len(rows)", len(rows)).Msg("getting log entries") + for _, row := range rows { + results[row.ReportID] = append(results[row.ReportID], row) + } + return results, nil +} diff --git a/platform/report.go b/platform/report.go deleted file mode 100644 index 7d011ff2..00000000 --- a/platform/report.go +++ /dev/null @@ -1,134 +0,0 @@ -package platform - -import ( - "context" - "fmt" - - "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/models" - "github.com/Gleipnir-Technology/nidus-sync/platform/event" - "github.com/Gleipnir-Technology/nidus-sync/platform/geocode" - "github.com/Gleipnir-Technology/nidus-sync/platform/report" - "github.com/Gleipnir-Technology/nidus-sync/platform/types" - "github.com/aarondl/opt/omit" - "github.com/aarondl/opt/omitnull" - "github.com/rs/zerolog/log" -) - -func ReportNuisanceCreate(ctx context.Context, setter_report models.PublicreportReportSetter, setter_nuisance models.PublicreportNuisanceSetter, latlng LatLng, address Address, images []ImageUpload) (*models.PublicreportReport, error) { - return reportCreate(ctx, setter_report, latlng, address, images, func(ctx context.Context, txn bob.Executor, report_id int32) error { - setter_nuisance.ReportID = omit.From(report_id) - _, err := models.PublicreportNuisances.Insert(&setter_nuisance).One(ctx, txn) - if err != nil { - return fmt.Errorf("Failed to create nuisance database record: %w", err) - } - return nil - }) -} - -func ReportWaterCreate(ctx context.Context, setter_report models.PublicreportReportSetter, setter_water models.PublicreportWaterSetter, latlng LatLng, address Address, images []ImageUpload) (*models.PublicreportReport, error) { - return reportCreate(ctx, setter_report, latlng, address, images, func(ctx context.Context, txn bob.Executor, report_id int32) error { - setter_water.ReportID = omit.From(report_id) - _, err := models.PublicreportWaters.Insert(&setter_water).One(ctx, txn) - if err != nil { - return fmt.Errorf("Failed to create water database record: %w", err) - } - return nil - }) -} - -type funcSetReportDetail = func(context.Context, bob.Executor, int32) error - -func reportCreate(ctx context.Context, setter_report models.PublicreportReportSetter, latlng LatLng, address Address, images []ImageUpload, detail_setter funcSetReportDetail) (result *models.PublicreportReport, err error) { - txn, err := db.PGInstance.BobDB.BeginTx(ctx, nil) - if err != nil { - return nil, fmt.Errorf("create txn: %w", err) - } - defer txn.Rollback(ctx) - - public_id, err := report.GenerateReportID() - if err != nil { - return nil, fmt.Errorf("create public ID: %w", err) - } - setter_report.PublicID = omit.From(public_id) - - // If we've got an locality value it was set by geocoding so we should save it - var a *models.Address - if address.Locality != "" && latlng.Latitude != nil && latlng.Longitude != nil { - a, err = geocode.EnsureAddress(ctx, txn, address, types.Location{ - Latitude: *latlng.Latitude, - Longitude: *latlng.Longitude, - }) - if err != nil { - return nil, fmt.Errorf("Failed to ensure address: %w", err) - } - } - - saved_images, err := saveImageUploads(ctx, txn, images) - if err != nil { - return nil, fmt.Errorf("Failed to save image uploads: %w", err) - } - var organization_id *int32 - organization_id, err = MatchDistrict(ctx, latlng.Longitude, latlng.Latitude, images) - if err != nil { - log.Warn().Err(err).Msg("Failed to match district") - } - - if a != nil { - setter_report.AddressID = omitnull.From(a.ID) - } - if organization_id != nil { - setter_report.OrganizationID = omit.FromPtr(organization_id) - } - result, err = models.PublicreportReports.Insert(&setter_report).One(ctx, txn) - if err != nil { - return nil, fmt.Errorf("Failed to create report database record: %w", err) - } - if latlng.Latitude != nil && latlng.Longitude != nil { - h3cell, _ := latlng.H3Cell() - geom_query, _ := latlng.GeometryQuery() - _, err = psql.Update( - um.Table("publicreport.report"), - um.SetCol("h3cell").ToArg(h3cell), - um.SetCol("location").To(geom_query), - um.Where(psql.Quote("id").EQ(psql.Arg(result.ID))), - ).Exec(ctx, txn) - if err != nil { - return nil, fmt.Errorf("Failed to insert publicreport.report geospatial", err) - } - } - log.Info().Str("public_id", public_id).Int32("id", result.ID).Msg("Created base report") - - if len(saved_images) > 0 { - setters := make([]*models.PublicreportReportImageSetter, 0) - for _, image := range saved_images { - setters = append(setters, &models.PublicreportReportImageSetter{ - ImageID: omit.From(int32(image.ID)), - ReportID: omit.From(int32(result.ID)), - }) - } - _, err = models.PublicreportReportImages.Insert(bob.ToMods(setters...)).Exec(ctx, txn) - if err != nil { - return nil, fmt.Errorf("Failed to save reference to images: %w", err) - } - log.Info().Int("len", len(images)).Msg("saved uploaded images") - } - - err = detail_setter(ctx, txn, result.ID) - if err != nil { - return nil, fmt.Errorf("detail setter: %w", err) - } - txn.Commit(ctx) - - if organization_id != nil { - event.Created( - event.TypeRMONuisance, - *organization_id, - result.PublicID, - ) - } - return result, nil -}