Rework mailer database schema, add UUID to mailers
At this point, I sent out our first test mailers for Delta.
This commit is contained in:
parent
a7bb6181c7
commit
a0eee3a95f
24 changed files with 2662 additions and 247 deletions
|
|
@ -7,6 +7,7 @@ import (
|
|||
"context"
|
||||
"fmt"
|
||||
"io"
|
||||
"strconv"
|
||||
"time"
|
||||
|
||||
"github.com/Gleipnir-Technology/bob"
|
||||
|
|
@ -20,6 +21,7 @@ import (
|
|||
"github.com/Gleipnir-Technology/bob/orm"
|
||||
"github.com/Gleipnir-Technology/bob/types/pgtypes"
|
||||
"github.com/aarondl/opt/omit"
|
||||
"github.com/stephenafamo/scan"
|
||||
)
|
||||
|
||||
// ComplianceReportRequest is an object representing the database table.
|
||||
|
|
@ -32,6 +34,8 @@ type ComplianceReportRequest struct {
|
|||
SiteVersion int32 `db:"site_version" `
|
||||
|
||||
R complianceReportRequestR `db:"-" `
|
||||
|
||||
C complianceReportRequestC `db:"-" `
|
||||
}
|
||||
|
||||
// ComplianceReportRequestSlice is an alias for a slice of pointers to ComplianceReportRequest.
|
||||
|
|
@ -46,8 +50,9 @@ type ComplianceReportRequestsQuery = *psql.ViewQuery[*ComplianceReportRequest, C
|
|||
|
||||
// complianceReportRequestR is where relationships are stored.
|
||||
type complianceReportRequestR struct {
|
||||
CreatorUser *User // compliance_report_request.compliance_report_request_creator_fkey
|
||||
Site *Site // compliance_report_request.compliance_report_request_site_id_site_version_fkey
|
||||
CreatorUser *User // compliance_report_request.compliance_report_request_creator_fkey
|
||||
Site *Site // compliance_report_request.compliance_report_request_site_id_site_version_fkey
|
||||
Mailers CommsMailerSlice // compliance_report_request_mailer.compliance_report_request_mai_compliance_report_request_id_fkeycompliance_report_request_mailer.compliance_report_request_mailer_mailer_id_fkey
|
||||
}
|
||||
|
||||
func buildComplianceReportRequestColumns(alias string) complianceReportRequestColumns {
|
||||
|
|
@ -514,6 +519,35 @@ func (os ComplianceReportRequestSlice) Site(mods ...bob.Mod[*dialect.SelectQuery
|
|||
)...)
|
||||
}
|
||||
|
||||
// Mailers starts a query for related objects on comms.mailer
|
||||
func (o *ComplianceReportRequest) Mailers(mods ...bob.Mod[*dialect.SelectQuery]) CommsMailersQuery {
|
||||
return CommsMailers.Query(append(mods,
|
||||
sm.InnerJoin(ComplianceReportRequestMailers.NameAs()).On(
|
||||
CommsMailers.Columns.ID.EQ(ComplianceReportRequestMailers.Columns.MailerID)),
|
||||
sm.Where(ComplianceReportRequestMailers.Columns.ComplianceReportRequestID.EQ(psql.Arg(o.ID))),
|
||||
)...)
|
||||
}
|
||||
|
||||
func (os ComplianceReportRequestSlice) Mailers(mods ...bob.Mod[*dialect.SelectQuery]) CommsMailersQuery {
|
||||
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 CommsMailers.Query(append(mods,
|
||||
sm.InnerJoin(ComplianceReportRequestMailers.NameAs()).On(
|
||||
CommsMailers.Columns.ID.EQ(ComplianceReportRequestMailers.Columns.MailerID),
|
||||
),
|
||||
sm.Where(psql.Group(ComplianceReportRequestMailers.Columns.ComplianceReportRequestID).OP("IN", PKArgExpr)),
|
||||
)...)
|
||||
}
|
||||
|
||||
func attachComplianceReportRequestCreatorUser0(ctx context.Context, exec bob.Executor, count int, complianceReportRequest0 *ComplianceReportRequest, user1 *User) (*ComplianceReportRequest, error) {
|
||||
setter := &ComplianceReportRequestSetter{
|
||||
Creator: omit.From(user1.ID),
|
||||
|
|
@ -665,6 +699,20 @@ func (o *ComplianceReportRequest) Preload(name string, retrieved any) error {
|
|||
rel.R.ComplianceReportRequests = ComplianceReportRequestSlice{o}
|
||||
}
|
||||
return nil
|
||||
case "Mailers":
|
||||
rels, ok := retrieved.(CommsMailerSlice)
|
||||
if !ok {
|
||||
return fmt.Errorf("complianceReportRequest cannot load %T as %q", retrieved, name)
|
||||
}
|
||||
|
||||
o.R.Mailers = rels
|
||||
|
||||
for _, rel := range rels {
|
||||
if rel != nil {
|
||||
rel.R.ComplianceReportRequests = ComplianceReportRequestSlice{o}
|
||||
}
|
||||
}
|
||||
return nil
|
||||
default:
|
||||
return fmt.Errorf("complianceReportRequest has no relationship %q", name)
|
||||
}
|
||||
|
|
@ -709,6 +757,7 @@ func buildComplianceReportRequestPreloader() complianceReportRequestPreloader {
|
|||
type complianceReportRequestThenLoader[Q orm.Loadable] struct {
|
||||
CreatorUser func(...bob.Mod[*dialect.SelectQuery]) orm.Loader[Q]
|
||||
Site func(...bob.Mod[*dialect.SelectQuery]) orm.Loader[Q]
|
||||
Mailers func(...bob.Mod[*dialect.SelectQuery]) orm.Loader[Q]
|
||||
}
|
||||
|
||||
func buildComplianceReportRequestThenLoader[Q orm.Loadable]() complianceReportRequestThenLoader[Q] {
|
||||
|
|
@ -718,6 +767,9 @@ func buildComplianceReportRequestThenLoader[Q orm.Loadable]() complianceReportRe
|
|||
type SiteLoadInterface interface {
|
||||
LoadSite(context.Context, bob.Executor, ...bob.Mod[*dialect.SelectQuery]) error
|
||||
}
|
||||
type MailersLoadInterface interface {
|
||||
LoadMailers(context.Context, bob.Executor, ...bob.Mod[*dialect.SelectQuery]) error
|
||||
}
|
||||
|
||||
return complianceReportRequestThenLoader[Q]{
|
||||
CreatorUser: thenLoadBuilder[Q](
|
||||
|
|
@ -732,6 +784,12 @@ func buildComplianceReportRequestThenLoader[Q orm.Loadable]() complianceReportRe
|
|||
return retrieved.LoadSite(ctx, exec, mods...)
|
||||
},
|
||||
),
|
||||
Mailers: thenLoadBuilder[Q](
|
||||
"Mailers",
|
||||
func(ctx context.Context, exec bob.Executor, retrieved MailersLoadInterface, mods ...bob.Mod[*dialect.SelectQuery]) error {
|
||||
return retrieved.LoadMailers(ctx, exec, mods...)
|
||||
},
|
||||
),
|
||||
}
|
||||
}
|
||||
|
||||
|
|
@ -843,10 +901,188 @@ func (os ComplianceReportRequestSlice) LoadSite(ctx context.Context, exec bob.Ex
|
|||
return nil
|
||||
}
|
||||
|
||||
// LoadMailers loads the complianceReportRequest's Mailers into the .R struct
|
||||
func (o *ComplianceReportRequest) LoadMailers(ctx context.Context, exec bob.Executor, mods ...bob.Mod[*dialect.SelectQuery]) error {
|
||||
if o == nil {
|
||||
return nil
|
||||
}
|
||||
|
||||
// Reset the relationship
|
||||
o.R.Mailers = nil
|
||||
|
||||
related, err := o.Mailers(mods...).All(ctx, exec)
|
||||
if err != nil {
|
||||
return err
|
||||
}
|
||||
|
||||
for _, rel := range related {
|
||||
rel.R.ComplianceReportRequests = ComplianceReportRequestSlice{o}
|
||||
}
|
||||
|
||||
o.R.Mailers = related
|
||||
return nil
|
||||
}
|
||||
|
||||
// LoadMailers loads the complianceReportRequest's Mailers into the .R struct
|
||||
func (os ComplianceReportRequestSlice) LoadMailers(ctx context.Context, exec bob.Executor, mods ...bob.Mod[*dialect.SelectQuery]) error {
|
||||
if len(os) == 0 {
|
||||
return nil
|
||||
}
|
||||
|
||||
// since we are changing the columns, we need to check if the original columns were set or add the defaults
|
||||
sq := dialect.SelectQuery{}
|
||||
for _, mod := range mods {
|
||||
mod.Apply(&sq)
|
||||
}
|
||||
|
||||
if len(sq.SelectList.Columns) == 0 {
|
||||
mods = append(mods, sm.Columns(CommsMailers.Columns))
|
||||
}
|
||||
|
||||
q := os.Mailers(append(
|
||||
mods,
|
||||
sm.Columns(ComplianceReportRequestMailers.Columns.ComplianceReportRequestID.As("related_compliance_report_request.ID")),
|
||||
)...)
|
||||
|
||||
IDSlice := []int32{}
|
||||
|
||||
mapper := scan.Mod(scan.StructMapper[*CommsMailer](), func(ctx context.Context, cols []string) (scan.BeforeFunc, func(any, any) error) {
|
||||
return func(row *scan.Row) (any, error) {
|
||||
IDSlice = append(IDSlice, *new(int32))
|
||||
row.ScheduleScanByName("related_compliance_report_request.ID", &IDSlice[len(IDSlice)-1])
|
||||
|
||||
return nil, nil
|
||||
},
|
||||
func(any, any) error {
|
||||
return nil
|
||||
}
|
||||
})
|
||||
|
||||
commsMailers, err := bob.Allx[bob.SliceTransformer[*CommsMailer, CommsMailerSlice]](ctx, exec, q, mapper)
|
||||
if err != nil {
|
||||
return err
|
||||
}
|
||||
|
||||
for _, o := range os {
|
||||
o.R.Mailers = nil
|
||||
}
|
||||
|
||||
for _, o := range os {
|
||||
for i, rel := range commsMailers {
|
||||
if !(o.ID == IDSlice[i]) {
|
||||
continue
|
||||
}
|
||||
|
||||
rel.R.ComplianceReportRequests = append(rel.R.ComplianceReportRequests, o)
|
||||
|
||||
o.R.Mailers = append(o.R.Mailers, rel)
|
||||
}
|
||||
}
|
||||
|
||||
return nil
|
||||
}
|
||||
|
||||
// complianceReportRequestC is where relationship counts are stored.
|
||||
type complianceReportRequestC struct {
|
||||
Mailers *int64
|
||||
}
|
||||
|
||||
// PreloadCount sets a count in the C struct by name
|
||||
func (o *ComplianceReportRequest) PreloadCount(name string, count int64) error {
|
||||
if o == nil {
|
||||
return nil
|
||||
}
|
||||
|
||||
switch name {
|
||||
case "Mailers":
|
||||
o.C.Mailers = &count
|
||||
}
|
||||
return nil
|
||||
}
|
||||
|
||||
type complianceReportRequestCountPreloader struct {
|
||||
Mailers func(...bob.Mod[*dialect.SelectQuery]) psql.Preloader
|
||||
}
|
||||
|
||||
func buildComplianceReportRequestCountPreloader() complianceReportRequestCountPreloader {
|
||||
return complianceReportRequestCountPreloader{
|
||||
Mailers: func(mods ...bob.Mod[*dialect.SelectQuery]) psql.Preloader {
|
||||
return countPreloader[*ComplianceReportRequest]("Mailers", func(parent string) bob.Expression {
|
||||
// Build a correlated subquery: (SELECT COUNT(*) FROM related WHERE fk = parent.pk)
|
||||
if parent == "" {
|
||||
parent = ComplianceReportRequests.Alias()
|
||||
}
|
||||
|
||||
subqueryMods := []bob.Mod[*dialect.SelectQuery]{
|
||||
sm.Columns(psql.Raw("count(*)")),
|
||||
|
||||
sm.From(ComplianceReportRequestMailers.Name()),
|
||||
sm.Where(psql.Quote(ComplianceReportRequestMailers.Alias(), "compliance_report_request_id").EQ(psql.Quote(parent, "id"))),
|
||||
sm.InnerJoin(CommsMailers.Name()).On(
|
||||
psql.Quote(CommsMailers.Alias(), "id").EQ(psql.Quote(ComplianceReportRequestMailers.Alias(), "mailer_id")),
|
||||
),
|
||||
}
|
||||
subqueryMods = append(subqueryMods, mods...)
|
||||
return psql.Group(psql.Select(subqueryMods...).Expression)
|
||||
})
|
||||
},
|
||||
}
|
||||
}
|
||||
|
||||
type complianceReportRequestCountThenLoader[Q orm.Loadable] struct {
|
||||
Mailers func(...bob.Mod[*dialect.SelectQuery]) orm.Loader[Q]
|
||||
}
|
||||
|
||||
func buildComplianceReportRequestCountThenLoader[Q orm.Loadable]() complianceReportRequestCountThenLoader[Q] {
|
||||
type MailersCountInterface interface {
|
||||
LoadCountMailers(context.Context, bob.Executor, ...bob.Mod[*dialect.SelectQuery]) error
|
||||
}
|
||||
|
||||
return complianceReportRequestCountThenLoader[Q]{
|
||||
Mailers: countThenLoadBuilder[Q](
|
||||
"Mailers",
|
||||
func(ctx context.Context, exec bob.Executor, retrieved MailersCountInterface, mods ...bob.Mod[*dialect.SelectQuery]) error {
|
||||
return retrieved.LoadCountMailers(ctx, exec, mods...)
|
||||
},
|
||||
),
|
||||
}
|
||||
}
|
||||
|
||||
// LoadCountMailers loads the count of Mailers into the C struct
|
||||
func (o *ComplianceReportRequest) LoadCountMailers(ctx context.Context, exec bob.Executor, mods ...bob.Mod[*dialect.SelectQuery]) error {
|
||||
if o == nil {
|
||||
return nil
|
||||
}
|
||||
|
||||
count, err := o.Mailers(mods...).Count(ctx, exec)
|
||||
if err != nil {
|
||||
return err
|
||||
}
|
||||
|
||||
o.C.Mailers = &count
|
||||
return nil
|
||||
}
|
||||
|
||||
// LoadCountMailers loads the count of Mailers for a slice
|
||||
func (os ComplianceReportRequestSlice) LoadCountMailers(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.LoadCountMailers(ctx, exec, mods...); err != nil {
|
||||
return err
|
||||
}
|
||||
}
|
||||
|
||||
return nil
|
||||
}
|
||||
|
||||
type complianceReportRequestJoins[Q dialect.Joinable] struct {
|
||||
typ string
|
||||
CreatorUser modAs[Q, userColumns]
|
||||
Site modAs[Q, siteColumns]
|
||||
Mailers modAs[Q, commsMailerColumns]
|
||||
}
|
||||
|
||||
func (j complianceReportRequestJoins[Q]) aliasedAs(alias string) complianceReportRequestJoins[Q] {
|
||||
|
|
@ -881,6 +1117,28 @@ func buildComplianceReportRequestJoins[Q dialect.Joinable](cols complianceReport
|
|||
))
|
||||
}
|
||||
|
||||
return mods
|
||||
},
|
||||
},
|
||||
Mailers: modAs[Q, commsMailerColumns]{
|
||||
c: CommsMailers.Columns,
|
||||
f: func(to commsMailerColumns) bob.Mod[Q] {
|
||||
random := strconv.FormatInt(randInt(), 10)
|
||||
mods := make(mods.QueryMods[Q], 0, 2)
|
||||
|
||||
{
|
||||
to := ComplianceReportRequestMailers.Columns.AliasedAs(ComplianceReportRequestMailers.Columns.Alias() + random)
|
||||
mods = append(mods, dialect.Join[Q](typ, ComplianceReportRequestMailers.Name().As(to.Alias())).On(
|
||||
to.ComplianceReportRequestID.EQ(cols.ID),
|
||||
))
|
||||
}
|
||||
{
|
||||
cols := ComplianceReportRequestMailers.Columns.AliasedAs(ComplianceReportRequestMailers.Columns.Alias() + random)
|
||||
mods = append(mods, dialect.Join[Q](typ, CommsMailers.Name().As(to.Alias())).On(
|
||||
to.ID.EQ(cols.MailerID),
|
||||
))
|
||||
}
|
||||
|
||||
return mods
|
||||
},
|
||||
},
|
||||
|
|
|
|||
Loading…
Add table
Add a link
Reference in a new issue