Overhaul email sending system

Add logging and saving templates to the database for historical
accuracy.
This commit is contained in:
Eli Ribble 2026-01-23 20:36:16 +00:00
parent 3fed489258
commit 196792810b
No known key found for this signature in database
44 changed files with 4846 additions and 2361 deletions

View file

@ -3,6 +3,8 @@ package background
import (
"context"
"sync"
"github.com/Gleipnir-Technology/nidus-sync/comms/email"
)
var waitGroup sync.WaitGroup
@ -10,9 +12,9 @@ var waitGroup sync.WaitGroup
func Start(ctx context.Context) {
newOAuthTokenChannel = make(chan struct{}, 10)
channelJobAudio = make(chan jobAudio, 100) // Buffered channel to prevent blocking
channelJobEmail = make(chan jobEmail, 100) // Buffered channel to prevent blocking
channelJobText = make(chan jobText, 100) // Buffered channel to prevent blocking
channelJobAudio = make(chan jobAudio, 100) // Buffered channel to prevent blocking
channelJobEmail = make(chan email.Job, 100) // Buffered channel to prevent blocking
channelJobText = make(chan jobText, 100) // Buffered channel to prevent blocking
waitGroup.Add(1)
go func() {

42
background/email.go Normal file
View file

@ -0,0 +1,42 @@
package background
import (
"context"
"github.com/Gleipnir-Technology/nidus-sync/comms/email"
"github.com/rs/zerolog/log"
)
var channelJobEmail chan email.Job
func ReportSubscriptionConfirmationEmail(destination, report_id string) {
enqueueJobEmail(email.NewJobReportSubscriptionConfirmation(
destination,
report_id,
))
}
func enqueueJobEmail(job email.Job) {
select {
case channelJobEmail <- job:
return
default:
log.Warn().Msg("email job channel is full, dropping job")
}
}
func startWorkerEmail(ctx context.Context, channel chan email.Job) {
go func() {
for {
select {
case <-ctx.Done():
log.Info().Msg("Email worker shutting down.")
return
case job := <-channel:
err := email.Handle(ctx, job)
if err != nil {
}
}
}
}()
}

View file

@ -11,17 +11,8 @@ import (
"github.com/rs/zerolog/log"
)
var channelJobEmail chan jobEmail
var channelJobText chan jobText
func ReportSubscriptionConfirmationEmail(destination string) {
enqueueJobEmail(jobEmail{
Destination: destination,
Source: config.ForwardEmailReportAddress,
Type: enums.CommsMessagetypeemailReportSubscriptionConfirmation,
})
}
func ReportSubscriptionConfirmationText(destination comms.E164, report_id string) {
enqueueJobText(jobText{
Destination: destination,
@ -31,12 +22,6 @@ func ReportSubscriptionConfirmationText(destination comms.E164, report_id string
})
}
type jobEmail struct {
Destination string
ReportID string
Source string
Type enums.CommsMessagetypeemail
}
type jobText struct {
Destination comms.E164
ReportID string
@ -44,15 +29,6 @@ type jobText struct {
Type enums.CommsMessagetypetext
}
func enqueueJobEmail(job jobEmail) {
select {
case channelJobEmail <- job:
log.Info().Str("destination", job.Destination).Msg("Enqueued email job")
default:
log.Warn().Msg("email job channel is full, dropping job")
}
}
func enqueueJobText(job jobText) {
select {
case channelJobText <- job:
@ -62,23 +38,6 @@ func enqueueJobText(job jobText) {
}
}
func startWorkerEmail(ctx context.Context, channel chan jobEmail) {
go func() {
for {
select {
case <-ctx.Done():
log.Info().Msg("Email worker shutting down.")
return
case job := <-channel:
err := jobProcessEmail(ctx, job)
if err != nil {
log.Error().Err(err).Str("dest", job.Destination).Str("type", string(job.Type)).Msg("Error processing email")
}
}
}
}()
}
func startWorkerText(ctx context.Context, channel chan jobText) {
go func() {
for {
@ -96,22 +55,6 @@ func startWorkerText(ctx context.Context, channel chan jobText) {
}()
}
func jobProcessEmail(ctx context.Context, job jobEmail) error {
switch job.Type {
case enums.CommsMessagetypeemailInitialContact:
return comms.SendEmailInitialContact(ctx, job.Destination)
default:
return errors.New("not implemented")
}
/*
case enums.CommsMessagetypeemailReportSubscriptionConfirmation:
case enums.CommsMessagetypeemailReportStatusScheduled:
case enums.CommsMessagetypeemailReportStatusComplete:
}
*/
}
func jobProcessText(job jobText) error {
var message string
switch job.Type {

View file

@ -1,245 +0,0 @@
package comms
import (
"bytes"
"context"
"embed"
"encoding/json"
"fmt"
"io"
"net/http"
"time"
"github.com/Gleipnir-Technology/nidus-sync/config"
"github.com/Gleipnir-Technology/nidus-sync/db"
"github.com/Gleipnir-Technology/nidus-sync/db/enums"
"github.com/Gleipnir-Technology/nidus-sync/db/models"
"github.com/Gleipnir-Technology/nidus-sync/htmlpage"
"github.com/aarondl/opt/omit"
"github.com/rs/zerolog/log"
)
func RenderEmailInitial(w http.ResponseWriter, destination string) {
content := newContentEmailInitial(destination)
renderOrError(w, initialT, content)
}
func RenderEmailReportConfirmation(w http.ResponseWriter, report_id string) {
content := newContentEmailSubscriptionConfirmation(report_id)
renderOrError(w, reportConfirmationT, content)
}
func SendEmailInitialContact(ctx context.Context, destination string) error {
content := newContentEmailInitial(destination)
text, html, err := renderEmailTemplates(reportConfirmationT, content)
if err != nil {
return fmt.Errorf("Failed to render email temlate: %w", err)
}
resp, err := sendEmail(ctx, emailRequest{
From: config.ForwardEmailReportAddress,
HTML: html,
Subject: "Welcome",
Text: text,
To: destination,
}, enums.CommsMessagetypeemailInitialContact)
if err != nil {
return fmt.Errorf("Failed to send email to %s: %w", err)
}
log.Info().Str("id", resp.ID).Str("to", destination).Msg("Sent initial contact email")
return nil
}
func SendEmailReportConfirmation(ctx context.Context, to string, report_id string) error {
report_id_str := publicReportID(report_id)
content := newContentEmailSubscriptionConfirmation(report_id)
text, html, err := renderEmailTemplates(reportConfirmationT, content)
if err != nil {
return fmt.Errorf("Failed to render template %s: %w", reportConfirmationT.name, err)
}
resp, err := sendEmail(ctx, emailRequest{
From: config.ForwardEmailReportAddress,
HTML: html,
Subject: fmt.Sprintf("Mosquito Report Submission - %s", report_id_str),
Text: text,
To: to,
}, enums.CommsMessagetypeemailReportSubscriptionConfirmation)
if err != nil {
return fmt.Errorf("Failed to send email report confirmation to %s for report %s: %w", to, report_id, err)
}
log.Info().Str("id", resp.ID).Str("to", to).Str("report_id", report_id).Msg("Sent report confirmation email")
return nil
}
var (
initialT = buildTemplate("initial")
reportConfirmationT = buildTemplate("report-subscription-confirmation")
)
//go:embed template/*
var embeddedFiles embed.FS
type attachmentRequest struct {
Filename string `json:"filename"`
Content string `json:"content"`
}
type contentEmailBase struct {
URLLogo string
URLUnsubscribe string
URLViewInBrowser string
}
type contentEmailReportConfirmation struct {
Base contentEmailBase
URLReportStatus string
}
type contentEmailInitial struct {
Base contentEmailBase
Destination string
URLSubscribe string
}
type emailRequest struct {
From string `json:"from"`
To string `json:"to"`
CC []string `json:"cc,omitempty"`
BCC []string `json:"bcc,omitempty"`
Subject string `json:"subject"`
Text string `json:"text"`
HTML string `json:"html,omitempty"`
Attachments []attachmentRequest `json:"attachments,omitempty"`
Sender string `json:"sender"`
ReplyTo string `json:"replyTo,omitempty"`
InReplyTo string `json:"inReplyTo,omitempty"`
References []string `json:"references,omitempty"`
}
type emailEnvelope struct {
From string `json:"from"`
To []string `json:"to"`
}
type emailResponse struct {
IsRedacted bool `json:"is_redacted"`
CreatedAt string `json:"created_at"`
HardBounces []string `json:"hard_bounces"`
SoftBounces []string `json:"soft_bounces"`
IsBounce bool `json:"is_bounce"`
Alias string `json:"alias"`
Domain string `json:"domain"`
User string `json:"user"`
Status string `json:"status"`
IsLocked bool `json:"is_locked"`
Envelope emailEnvelope `json:"envelope"`
RequireTLS bool `json:"requireTLS"`
MessageID string `json:"messageId"`
Headers map[string]string `json:"headers"`
Date string `json:"date"`
Subject string `json:"subject"`
Accepted []string `json:"accepted"`
Deliveries []string `json:"deliveries"`
RejectedErrors []string `json:"rejectedErrors"`
ID string `json:"id"`
Object string `json:"object"`
UpdatedAt string `json:"updated_at"`
Link string `json:"link"`
Message string `json:"message"`
}
func newContentBase(b *contentEmailBase, url string) {
b.URLLogo = config.MakeURLReport("/static/img/nidus-logo-no-lettering-64.png")
b.URLUnsubscribe = config.MakeURLReport("/email/unsubscribe")
b.URLViewInBrowser = url
}
func newContentEmailInitial(destination string) (result contentEmailInitial) {
newContentBase(
&result.Base,
config.MakeURLReport("/email/initial"),
)
result.Destination = destination
result.URLSubscribe = config.MakeURLReport("/email/subscribe?email=%s", destination)
return result
}
func newContentEmailSubscriptionConfirmation(report_id string) (result contentEmailReportConfirmation) {
newContentBase(
&result.Base,
config.MakeURLReport("/email/report/%s/subscription-confirmation", report_id),
)
result.URLReportStatus = config.MakeURLReport("/status/%s", report_id)
return result
}
func publicReportID(s string) string {
if len(s) != 12 {
return s
}
return s[0:4] + "-" + s[4:8] + "-" + s[8:12]
}
func renderOrError(w http.ResponseWriter, template *builtTemplate, context interface{}) {
buf := &bytes.Buffer{}
err := template.executeTemplateHTML(buf, context)
if err != nil {
log.Error().Err(err).Str("name", template.name).Msg("Failed to render template")
htmlpage.RespondError(w, "Failed to render template", err, http.StatusInternalServerError)
return
}
buf.WriteTo(w)
}
var FORWARDEMAIL_API = "https://api.forwardemail.net/v1/emails"
func ensureInDB(ctx context.Context, destination string) (err error) {
_, err = models.FindCommsEmail(ctx, db.PGInstance.BobDB, destination)
if err != nil {
// assume it exists
log.Warn().Err(err).Msg("ElI, check what this error should look like")
return nil
}
_, err = models.CommsEmails.Insert(&models.CommsEmailSetter{
Address: omit.From(destination),
Confirmed: omit.From(false),
IsSubscribed: omit.From(false),
}).One(ctx, db.PGInstance.BobDB)
if err != nil {
return fmt.Errorf("Failed to insert new email: %w", err)
}
log.Info().Str("email", destination).Msg("Added email to the comms database")
return nil
}
func insertEmailLog(ctx context.Context, email emailRequest, t enums.CommsMessagetypeemail) (err error) {
_, err = models.CommsEmailLogs.Insert(&models.CommsEmailLogSetter{
Created: omit.From(time.Now()),
Destination: omit.From(email.To),
Source: omit.From(email.From),
Type: omit.From(t),
}).One(ctx, db.PGInstance.BobDB)
return err
}
func sendEmail(ctx context.Context, email emailRequest, t enums.CommsMessagetypeemail) (response emailResponse, err error) {
ensureInDB(ctx, email.To)
payload, err := json.Marshal(email)
if err != nil {
return response, fmt.Errorf("Failed to marshal email request: %w", err)
}
insertEmailLog(ctx, email, t)
req, _ := http.NewRequest("POST", FORWARDEMAIL_API, bytes.NewReader(payload))
req.SetBasicAuth(config.ForwardEmailAPIToken, "")
req.Header.Add("Content-Type", "application/json")
res, _ := http.DefaultClient.Do(req)
defer res.Body.Close()
body, _ := io.ReadAll(res.Body)
// Parse the JSON response
err = json.Unmarshal(body, &response)
if err != nil {
log.Warn().Str("status", res.Status).Str("response_body", string(body)).Msg("Attempted to send email but couldn't parse the resulting JSON")
return response, fmt.Errorf("Failed to unmarshal JSON response: %w", err)
}
return response, nil
}

103
comms/email/db.go Normal file
View file

@ -0,0 +1,103 @@
package email
import (
"context"
"crypto/sha256"
"database/sql"
"encoding/hex"
"fmt"
"sort"
"strings"
"time"
"github.com/Gleipnir-Technology/nidus-sync/db"
"github.com/Gleipnir-Technology/nidus-sync/db/enums"
"github.com/Gleipnir-Technology/nidus-sync/db/models"
"github.com/aarondl/opt/omit"
"github.com/aarondl/opt/omitnull"
"github.com/rs/zerolog/log"
"github.com/stephenafamo/bob/types/pgtypes"
)
func convertToPGData(data map[string]string) pgtypes.HStore {
result := pgtypes.HStore{}
for k, v := range data {
result[k] = sql.Null[string]{V: v, Valid: true}
}
return result
}
func ensureInDB(ctx context.Context, destination string) (err error) {
_, err = models.FindCommsEmailContact(ctx, db.PGInstance.BobDB, destination)
if err != nil {
// doesn't exist
if err.Error() == "sql: no rows in result set" {
public_id := fmt.Sprintf("%x", sha256.Sum256([]byte(destination)))
_, err = models.CommsEmailContacts.Insert(&models.CommsEmailContactSetter{
Address: omit.From(destination),
Confirmed: omit.From(false),
IsSubscribed: omit.From(false),
PublicID: omit.From(public_id),
}).One(ctx, db.PGInstance.BobDB)
if err != nil {
return fmt.Errorf("Failed to insert new email: %w", err)
}
log.Info().Str("email", destination).Msg("Added email to the comms database")
return nil
}
return fmt.Errorf("Unexpected error searching for contact: %w", err)
}
return nil
}
func insertEmailLog(ctx context.Context, data map[string]string, destination string, public_id string, source string, subject string, template_id int32) (err error) {
data_for_insert := convertToPGData(data)
_, err = models.CommsEmailLogs.Insert(&models.CommsEmailLogSetter{
//ID:
Created: omit.From(time.Now()),
DeliveryStatus: omit.From("initial"),
Destination: omit.From(destination),
PublicID: omit.From(public_id),
SentAt: omitnull.FromPtr[time.Time](nil),
Source: omit.From(source),
Subject: omit.From(subject),
TemplateID: omitnull.From(templateInitialID),
TemplateData: omit.From(data_for_insert),
Type: omit.From(enums.CommsMessagetypeemailInitialContact),
}).One(ctx, db.PGInstance.BobDB)
return err
}
func generatePublicId(t enums.CommsMessagetypeemail, m map[string]string) string {
if m == nil || len(m) == 0 {
// Return hash of empty string for empty maps
emptyHash := sha256.Sum256([]byte(""))
return hex.EncodeToString(emptyHash[:])
}
// Get and sort keys for deterministic ordering
keys := make([]string, 0, len(m))
for k := range m {
keys = append(keys, k)
}
sort.Strings(keys)
// Build a string with all key-value pairs
var sb strings.Builder
// Add type first
sb.WriteString(fmt.Sprintf("type:%s,", t))
for _, k := range keys {
sb.WriteString(k)
sb.WriteString(":") // Separator between key and value
sb.WriteString(m[k])
sb.WriteString(",") // Separator between pairs
}
// Compute SHA-256 hash
hasher := sha256.New()
hasher.Write([]byte(sb.String()))
hashBytes := hasher.Sum(nil)
// Convert to hex string and return
return hex.EncodeToString(hashBytes)
}

108
comms/email/email.go Normal file
View file

@ -0,0 +1,108 @@
package email
import (
"bytes"
"context"
"encoding/json"
"fmt"
"io"
"net/http"
"github.com/Gleipnir-Technology/nidus-sync/config"
"github.com/Gleipnir-Technology/nidus-sync/db/enums"
"github.com/rs/zerolog/log"
)
type attachmentRequest struct {
Filename string `json:"filename"`
Content string `json:"content"`
}
type contentEmailBase struct {
URLLogo string
URLUnsubscribe string
URLViewInBrowser string
}
type contentEmailReportConfirmation struct {
Base contentEmailBase
URLReportStatus string
}
type contentEmailInitial struct {
Base contentEmailBase
Destination string
URLSubscribe string
}
type emailRequest struct {
From string `json:"from"`
To string `json:"to"`
CC []string `json:"cc,omitempty"`
BCC []string `json:"bcc,omitempty"`
Subject string `json:"subject"`
Text string `json:"text"`
HTML string `json:"html,omitempty"`
Attachments []attachmentRequest `json:"attachments,omitempty"`
Sender string `json:"sender"`
ReplyTo string `json:"replyTo,omitempty"`
InReplyTo string `json:"inReplyTo,omitempty"`
References []string `json:"references,omitempty"`
}
type emailEnvelope struct {
From string `json:"from"`
To []string `json:"to"`
}
type emailResponse struct {
IsRedacted bool `json:"is_redacted"`
CreatedAt string `json:"created_at"`
HardBounces []string `json:"hard_bounces"`
SoftBounces []string `json:"soft_bounces"`
IsBounce bool `json:"is_bounce"`
Alias string `json:"alias"`
Domain string `json:"domain"`
User string `json:"user"`
Status string `json:"status"`
IsLocked bool `json:"is_locked"`
Envelope emailEnvelope `json:"envelope"`
RequireTLS bool `json:"requireTLS"`
MessageID string `json:"messageId"`
Headers map[string]string `json:"headers"`
Date string `json:"date"`
Subject string `json:"subject"`
Accepted []string `json:"accepted"`
Deliveries []string `json:"deliveries"`
RejectedErrors []string `json:"rejectedErrors"`
ID string `json:"id"`
Object string `json:"object"`
UpdatedAt string `json:"updated_at"`
Link string `json:"link"`
Message string `json:"message"`
}
var FORWARDEMAIL_API = "https://api.forwardemail.net/v1/emails"
func sendEmail(ctx context.Context, email emailRequest, t enums.CommsMessagetypeemail) (response emailResponse, err error) {
payload, err := json.Marshal(email)
if err != nil {
return response, fmt.Errorf("Failed to marshal email request: %w", err)
}
req, _ := http.NewRequest("POST", FORWARDEMAIL_API, bytes.NewReader(payload))
req.SetBasicAuth(config.ForwardEmailAPIToken, "")
req.Header.Add("Content-Type", "application/json")
res, _ := http.DefaultClient.Do(req)
defer res.Body.Close()
body, _ := io.ReadAll(res.Body)
// Parse the JSON response
err = json.Unmarshal(body, &response)
if err != nil {
log.Warn().Str("status", res.Status).Str("response_body", string(body)).Msg("Attempted to send email but couldn't parse the resulting JSON")
return response, fmt.Errorf("Failed to unmarshal JSON response: %w", err)
}
return response, nil
}

74
comms/email/initial.go Normal file
View file

@ -0,0 +1,74 @@
package email
import (
"context"
"fmt"
"github.com/Gleipnir-Technology/nidus-sync/config"
"github.com/Gleipnir-Technology/nidus-sync/db"
"github.com/Gleipnir-Technology/nidus-sync/db/enums"
"github.com/Gleipnir-Technology/nidus-sync/db/models"
"github.com/rs/zerolog/log"
)
type jobInitial struct {
base jobEmailBase
}
func (job jobInitial) Destination() string {
return job.base.destination
}
func maybeSendInitialEmail(ctx context.Context, destination string) error {
err := ensureInDB(ctx, destination)
if err != nil {
return fmt.Errorf("Failed to add email recipient to database: %w", err)
}
rows, err := models.CommsEmailLogs.Query(
models.SelectWhere.CommsEmailLogs.Destination.EQ(destination),
models.SelectWhere.CommsEmailLogs.TemplateID.EQ(templateInitialID),
).All(ctx, db.PGInstance.BobDB)
// We already sent an initial email
if len(rows) > 0 {
return nil
}
return sendEmailInitialContact(ctx, destination)
}
func sendEmailInitialContact(ctx context.Context, destination string) error {
//data := pgtypes.HStore{}
data := make(map[string]string, 0)
source := config.ForwardEmailReportAddress
data["destination"] = destination
data["source"] = source
data["url_logo"] = config.MakeURLReport("/static/img/nidus-logo-no-lettering-64.png")
data["url_subscribe"] = config.MakeURLReport("/email/subscribe?email=%s", destination)
data["url_unsubscribe"] = config.MakeURLReport("/email/unsubscribe")
public_id := generatePublicId(enums.CommsMessagetypeemailInitialContact, data)
data["url_browser"] = config.MakeURLReport("/email?id=%s", public_id)
text, html, err := renderEmailTemplates(templateInitialID, data)
if err != nil {
return fmt.Errorf("Failed to render email temlates: %w", err)
}
subject := "Welcome"
err = insertEmailLog(ctx, data, destination, public_id, source, subject, templateInitialID)
if err != nil {
return fmt.Errorf("Failed to store email log: %w", err)
}
resp, err := sendEmail(ctx, emailRequest{
From: source,
HTML: html,
Subject: subject,
Text: text,
To: destination,
}, enums.CommsMessagetypeemailInitialContact)
if err != nil {
return fmt.Errorf("Failed to send email to %s: %w", err)
}
log.Info().Str("id", resp.ID).Str("to", destination).Msg("Sent initial contact email")
return nil
}

44
comms/email/job.go Normal file
View file

@ -0,0 +1,44 @@
package email
import (
"context"
"errors"
"fmt"
"github.com/Gleipnir-Technology/nidus-sync/db/enums"
"github.com/rs/zerolog/log"
)
type Job interface {
destination() string
messageType() enums.CommsMessagetypeemail
renderHTML() (string, error)
renderTXT() (string, error)
subject() string
}
type jobEmailBase struct {
destination string
source string
}
func Handle(ctx context.Context, job Job) error {
var err error
switch job.messageType() {
case enums.CommsMessagetypeemailReportSubscriptionConfirmation:
err = sendEmailReportConfirmation(ctx, job)
default:
return errors.New("not implemented")
}
if err != nil {
log.Error().Err(err).Str("dest", job.destination()).Str("type", string(job.messageType())).Msg("Error processing email")
return fmt.Errorf("Failed to handle email: %w", err)
}
return nil
/*
case enums.CommsMessagetypeemailReportStatusScheduled:
case enums.CommsMessagetypeemailReportStatusComplete:
}
*/
}

View file

@ -0,0 +1,80 @@
package email
import (
"context"
"fmt"
"github.com/Gleipnir-Technology/nidus-sync/config"
"github.com/Gleipnir-Technology/nidus-sync/db/enums"
//"github.com/rs/zerolog/log"
)
func NewJobReportSubscriptionConfirmation(destination, report_id string) Job {
return jobEmailReportSubscriptionConfirmation{
dest: destination,
reportID: report_id,
}
}
type jobEmailReportSubscriptionConfirmation struct {
dest string
reportID string
}
func (job jobEmailReportSubscriptionConfirmation) destination() string {
return job.dest
}
func (job jobEmailReportSubscriptionConfirmation) messageType() enums.CommsMessagetypeemail {
return enums.CommsMessagetypeemailReportSubscriptionConfirmation
}
func (job jobEmailReportSubscriptionConfirmation) renderHTML() (string, error) {
_ = newContentEmailSubscriptionConfirmation(job)
return "", nil
}
func (job jobEmailReportSubscriptionConfirmation) renderTXT() (string, error) {
return "fake txt", nil
}
func (job jobEmailReportSubscriptionConfirmation) subject() string {
return ""
}
func sendEmailReportConfirmation(ctx context.Context, job Job) error {
j, ok := job.(jobEmailReportSubscriptionConfirmation)
if !ok {
return fmt.Errorf("job is not for report subscription confirmation")
}
err := maybeSendInitialEmail(ctx, j.destination())
if err != nil {
return fmt.Errorf("Failed to handle initial email: %w", err)
}
return nil
/*
report_id_str := publicReportID(report_id)
content := newContentEmailSubscriptionConfirmation(report_id)
text, html, err := renderEmailTemplates(reportConfirmationT, content)
if err != nil {
return fmt.Errorf("Failed to render template %s: %w", reportConfirmationT.name, err)
}
resp, err := sendEmail(ctx, emailRequest{
From: config.ForwardEmailReportAddress,
HTML: html,
Subject: fmt.Sprintf("Mosquito Report Submission - %s", report_id_str),
Text: text,
To: to,
}, enums.CommsMessagetypeemailReportSubscriptionConfirmation)
if err != nil {
return fmt.Errorf("Failed to send email report confirmation to %s for report %s: %w", to, report_id, err)
}
log.Info().Str("id", resp.ID).Str("to", to).Str("report_id", report_id).Msg("Sent report confirmation email")
return nil
*/
}
func newContentEmailSubscriptionConfirmation(job jobEmailReportSubscriptionConfirmation) (result contentEmailReportConfirmation) {
/*newContentBase(
&result.Base,
config.MakeURLReport("/email/report/%s/subscription-confirmation", job.reportID),
)*/
result.URLReportStatus = config.MakeURLReport("/status/%s", job.reportID)
return result
}

319
comms/email/template.go Normal file
View file

@ -0,0 +1,319 @@
package email
import (
"bytes"
"context"
"crypto/sha256"
"embed"
"errors"
"fmt"
templatehtml "html/template"
"io"
"io/fs"
"path"
"path/filepath"
"strings"
templatetxt "text/template"
"time"
"github.com/Gleipnir-Technology/nidus-sync/db"
"github.com/Gleipnir-Technology/nidus-sync/db/enums"
"github.com/Gleipnir-Technology/nidus-sync/db/models"
"github.com/aarondl/opt/omit"
"github.com/aarondl/opt/omitnull"
"github.com/rs/zerolog/log"
"github.com/stephenafamo/bob"
"github.com/stephenafamo/bob/dialect/psql"
"github.com/stephenafamo/bob/dialect/psql/um"
)
//go:embed template/*
var embeddedFiles embed.FS
var (
templateByID map[int32]*builtTemplate
templateInitialID int32
)
type templatePair struct {
baseName string
messageType enums.CommsMessagetypeemail
htmlContent string
txtContent string
htmlHash string
txtHash string
}
func LoadTemplates() error {
all_templates, err := readTemplates(embeddedFiles)
if err != nil {
return fmt.Errorf("Failed to read templates: %w", err)
}
ctx := context.TODO()
tx, err := db.PGInstance.BobDB.BeginTx(ctx, nil)
if err != nil {
return fmt.Errorf("Failed to start transaction: %w", err)
}
defer tx.Rollback(ctx)
templateByID = make(map[int32]*builtTemplate, 0)
for name, p := range all_templates {
template_id, err := templateDBID(tx, name, p)
if err != nil {
return fmt.Errorf("Failed to add '%s' to DB: %w", name, err)
}
template_html, err := templatehtml.New(name).Parse(p.htmlContent)
if err != nil {
return fmt.Errorf("Failed to parse HTML portion of '%s': %w", name, err)
}
template_txt, err := templatetxt.New(name).Parse(p.txtContent)
if err != nil {
return fmt.Errorf("Failed to parse HTML portion of '%s': %w", name, err)
}
built := builtTemplate{
name: name,
templateHTML: template_html,
templateTXT: template_txt,
}
templateByID[template_id] = &built
log.Info().Int32("id", template_id).Str("name", name).Msg("Added template to cache")
}
templateInitialID, err = loadTemplateID(ctx, tx, enums.CommsMessagetypeemailInitialContact)
if err != nil {
return fmt.Errorf("Failed to load template ID: %s", err)
}
tx.Commit(ctx)
return nil
}
func loadTemplateID(ctx context.Context, tx bob.Tx, t enums.CommsMessagetypeemail) (int32, error) {
templates, err := models.CommsEmailTemplates.Query(
models.SelectWhere.CommsEmailTemplates.MessageType.EQ(t),
models.SelectWhere.CommsEmailTemplates.Superceded.IsNull(),
).All(ctx, tx)
if err != nil {
return 0, fmt.Errorf("Failed to query template '%s': %w", t, err)
}
switch len(templates) {
case 0:
return 0, fmt.Errorf("No matching templates for '%s", t)
case 1:
return templates[0].ID, nil
default:
return 0, fmt.Errorf("Found %d templates for '%s', should only have 1", len(templates), t)
}
}
func readTemplates(filesystem embed.FS) (results map[string]*templatePair, err error) {
// First pass: read files and organize by base name
results = make(map[string]*templatePair)
err = fs.WalkDir(filesystem, ".", func(path string, d fs.DirEntry, err error) error {
if err != nil {
return err
}
if d.IsDir() {
return nil
}
// Read file content
content, err := filesystem.ReadFile(path)
if err != nil {
return fmt.Errorf("error reading template %s: %w", path, err)
}
// Calculate hash
hash := fmt.Sprintf("%x", sha256.Sum256(content))
// Extract base name and extension
ext := strings.ToLower(filepath.Ext(path))
baseName := strings.TrimSuffix(filepath.Base(path), ext)
// Store in map by base name
if _, exists := results[baseName]; !exists {
t, err := messageTypeFromName(baseName)
if err != nil {
return fmt.Errorf("Cannot parse email templates: %w", err)
}
results[baseName] = &templatePair{
baseName: baseName,
messageType: *t,
}
}
// Add content based on extension
switch ext {
case ".html", ".htm":
results[baseName].htmlContent = string(content)
results[baseName].htmlHash = hash
case ".txt":
results[baseName].txtContent = string(content)
results[baseName].txtHash = hash
}
return nil
})
if err != nil {
return results, fmt.Errorf("error walking template directory: %w", err)
}
return results, nil
}
func templateDBID(tx bob.Tx, name string, pair *templatePair) (int32, error) {
ctx := context.Background()
// Skip incomplete pairs
if pair.htmlContent == "" {
return 0, fmt.Errorf("Bad template pair '%s': no html content")
}
if pair.txtContent == "" {
return 0, fmt.Errorf("Bad template pair '%s': no txt content")
}
// Check if a template with these hashes already exists
rows, err := models.CommsEmailTemplates.Query(
models.SelectWhere.CommsEmailTemplates.ContentHashHTML.EQ(pair.htmlHash),
models.SelectWhere.CommsEmailTemplates.ContentHashTXT.EQ(pair.txtHash),
models.SelectWhere.CommsEmailTemplates.MessageType.EQ(pair.messageType),
).All(ctx, tx)
if err != nil {
return 0, fmt.Errorf("Failed to query for existing template: %w", err)
}
if len(rows) > 1 {
return 0, fmt.Errorf("Got %d template rows, should only have 1", len(rows))
} else if len(rows) == 1 {
return rows[0].ID, nil
}
// Supercede previous templates of this type
_, err = psql.Update(
um.Table(models.CommsEmailTemplates.Alias()),
um.SetCol("superceded").ToArg(time.Now()),
//um.Where(models.CommsEmailTemplates.Columns.MessageType.EQ(psql.Arg(pair.messageType))),
um.Where(psql.Quote("message_type").EQ(psql.Arg(pair.messageType))),
//um.Where(models.CommsEmailTemplates.Columns.Superceded.IsNull()),
um.Where(psql.Quote("superceded").IsNull()),
).Exec(ctx, tx)
if err != nil {
return 0, fmt.Errorf("error superceding templates: %w", err)
}
new_template, err := models.CommsEmailTemplates.Insert(&models.CommsEmailTemplateSetter{
ContentHTML: omit.From(pair.htmlContent),
ContentTXT: omit.From(pair.txtContent),
ContentHashHTML: omit.From(pair.htmlHash),
ContentHashTXT: omit.From(pair.txtHash),
Created: omit.From(time.Now()),
Superceded: omitnull.FromPtr[time.Time](nil),
MessageType: omit.From(pair.messageType),
}).One(ctx, tx)
if err != nil {
return 0, fmt.Errorf("Failed to insert new template: %w", err)
}
log.Info().Int32("id", new_template.ID).Str("type", string(pair.messageType)).Msg("Added new email template")
return new_template.ID, nil
}
type builtTemplate struct {
name string
templateHTML *templatehtml.Template
templateTXT *templatetxt.Template
}
func (bt *builtTemplate) executeTemplateHTML(w io.Writer, content any) error {
if bt.templateHTML == nil {
file := templateFileHTML(bt.name)
templ, err := parseFromDiskHTML(file)
if err != nil {
return fmt.Errorf("Failed to parse template file: %w", err)
}
if templ == nil {
w.Write([]byte("Failed to read from disk: "))
return errors.New("Template parsing failed")
}
//log.Debug().Str("name", templ.Name()).Msg("Parsed template")
return templ.ExecuteTemplate(w, bt.name, content)
} else {
return bt.templateHTML.ExecuteTemplate(w, bt.name, content)
}
}
func (bt *builtTemplate) executeTemplateTXT(w io.Writer, content any) error {
if bt.templateTXT == nil {
file := templateFileTXT(bt.name)
templ, err := parseFromDiskTXT(file)
if err != nil {
return fmt.Errorf("Failed to parse template file: %w", err)
}
if templ == nil {
w.Write([]byte("Failed to read from disk: "))
return errors.New("Template parsing failed")
}
//log.Debug().Str("name", templ.Name()).Msg("Parsed template")
return templ.ExecuteTemplate(w, bt.name, content)
} else {
return bt.templateTXT.ExecuteTemplate(w, bt.name, content)
}
}
func templateFileHTML(name string) string {
return fmt.Sprintf("comms/template/%s.html", name)
}
func templateFileTXT(name string) string {
return fmt.Sprintf("comms/template/%s.txt", name)
}
func messageTypeFromName(n string) (*enums.CommsMessagetypeemail, error) {
for _, t := range enums.AllCommsMessagetypeemail() {
if n == string(t) {
return &t, nil
}
}
return nil, fmt.Errorf("Unrecognized email type '%s'", n)
}
func parseFromDiskHTML(file string) (*templatehtml.Template, error) {
name := path.Base(file)
//log.Debug().Str("name", name).Strs("files", files).Msg("parsing from disk")
templ, err := templatehtml.New(name).ParseFiles(file)
if err != nil {
return nil, fmt.Errorf("Failed to parse %s: %w", file, err)
}
return templ, nil
}
func parseFromDiskTXT(file string) (*templatetxt.Template, error) {
name := path.Base(file)
//log.Debug().Str("name", name).Strs("files", files).Msg("parsing from disk")
templ, err := templatetxt.New(name).ParseFiles(file)
if err != nil {
return nil, fmt.Errorf("Failed to parse %s: %w", file, err)
}
return templ, nil
}
func publicReportID(s string) string {
if len(s) != 12 {
return s
}
return s[0:4] + "-" + s[4:8] + "-" + s[8:12]
}
func renderEmailTemplates(template_id int32, content map[string]string) (text string, html string, err error) {
buf_txt := &bytes.Buffer{}
t, ok := templateByID[template_id]
if !ok {
return "", "", fmt.Errorf("Failed to lookup template %d", template_id)
}
err = t.executeTemplateTXT(buf_txt, content)
if err != nil {
return "", "", fmt.Errorf("Failed to render TXT template: %w", err)
}
buf_html := &bytes.Buffer{}
err = t.executeTemplateHTML(buf_html, content)
if err != nil {
return "", "", fmt.Errorf("Failed to render HTML template: %w", err)
}
return buf_txt.String(), buf_html.String(), nil
}

View file

@ -65,31 +65,31 @@
<body>
<div class="container">
<div class="view-browser">
Email not displaying correctly? <a href="{{.Base.URLViewInBrowser}}">View it in your browser</a>
Email not displaying correctly? <a href="{{.url_browser}}">View it in your browser</a>
</div>
<div class="header">
<!-- Logo Placeholder -->
<img src="{{.Base.URLLogo}}" alt="Report Mosquitoes Online Logo" class="logo"></img>
<img src="{{.url_logo}}" alt="Report Mosquitoes Online Logo" class="logo"></img>
</div>
<div class="content">
<h1>Welcome</h1>
<p>We're sending you this email because it's the first time we've gotten this email address ({{.Destination}}).</p>
<p>We're sending you this email because it's the first time we've gotten this email address ({{.destination}}).</p>
<p>If you'd rather not receive emails from us you can reply with "Unsubscribe" in the subject or body of the email. You can also use the "Unsubscribe" feature of your mail client, if it supports list unsubscribes.</p>
<p>If instead you'd like to confirm that you're willing to receive emails at this address, you can do so by clicking below:</p>
<div style="text-align: center;">
<a href="{{.URLSubscribe}}" class="button">I want emails from Report Mosquitoes Online</a>
<a href="{{.url_subscribe}}" class="button">I want emails from Report Mosquitoes Online</a>
</div>
</div>
<div class="footer">
<p>This email was sent to you because you or someone else gave your email address to Report Mosquitoes Online.</p>
<p>If you no longer wish to receive these updates, <a href="{{.Base.URLUnsubscribe}}">click here to unsubscribe</a>.</p>
<p>If you no longer wish to receive these updates, <a href="{{.url_unsubscribe}}">click here to unsubscribe</a>.</p>
<p>&copy; 2026 Gleipnir LLC. All rights reserved.</p>
</div>
</div>

View file

@ -0,0 +1,7 @@
We're sending you this email because it's the first time we've gotten this email address ({{.Destination}}).
If you'd rather not receive emails from us you can reply with "Unsubscribe" in the subject or body of the email. You can also use the "Unsubscribe" feature of your mail client, if it supports list unsubscribes.
If instead you'd like to confirm that you're willing to receive emails at this address, you can do so by openining the following URL in a web browser: {{.URLSubscribe}}. You can also confirm your willingness by replying to this email with 'Confirm' in the subject on the body of the email.
Thank you,
Report Mosquitoes Online

View file

@ -1,148 +0,0 @@
package comms
import (
"bytes"
"embed"
"errors"
"fmt"
templatehtml "html/template"
"io"
"os"
"path"
"strings"
templatetxt "text/template"
"github.com/Gleipnir-Technology/nidus-sync/config"
"github.com/rs/zerolog/log"
)
type builtTemplate struct {
name string
templateHTML *templatehtml.Template
templateTXT *templatetxt.Template
}
func (bt *builtTemplate) executeTemplateHTML(w io.Writer, content any) error {
if bt.templateHTML == nil {
file := templateFileHTML(bt.name)
templ, err := parseFromDiskHTML(file)
if err != nil {
return fmt.Errorf("Failed to parse template file: %w", err)
}
if templ == nil {
w.Write([]byte("Failed to read from disk: "))
return errors.New("Template parsing failed")
}
//log.Debug().Str("name", templ.Name()).Msg("Parsed template")
return templ.ExecuteTemplate(w, bt.name+".html", content)
} else {
return bt.templateHTML.ExecuteTemplate(w, bt.name+".html", content)
}
}
func (bt *builtTemplate) executeTemplateTXT(w io.Writer, content any) error {
if bt.templateTXT == nil {
file := templateFileTXT(bt.name)
templ, err := parseFromDiskTXT(file)
if err != nil {
return fmt.Errorf("Failed to parse template file: %w", err)
}
if templ == nil {
w.Write([]byte("Failed to read from disk: "))
return errors.New("Template parsing failed")
}
//log.Debug().Str("name", templ.Name()).Msg("Parsed template")
return templ.ExecuteTemplate(w, bt.name+".txt", content)
} else {
return bt.templateTXT.ExecuteTemplate(w, bt.name+".txt", content)
}
}
func templateFileHTML(name string) string {
return fmt.Sprintf("comms/template/%s.html", name)
}
func templateFileTXT(name string) string {
return fmt.Sprintf("comms/template/%s.txt", name)
}
func buildTemplate(name string) *builtTemplate {
files_on_disk := true
file_html := templateFileHTML(name)
file_txt := templateFileTXT(name)
for _, f := range []string{file_html, file_txt} {
_, err := os.Stat(f)
if err != nil {
files_on_disk = false
if !config.IsProductionEnvironment() {
log.Warn().Str("file", f).Msg("email template file is not on disk")
}
break
}
}
var result builtTemplate
if files_on_disk {
result = builtTemplate{
name: name,
templateHTML: nil,
templateTXT: nil,
}
} else {
result = builtTemplate{
name: name,
templateHTML: parseEmbeddedHTML(embeddedFiles, "comms", file_html),
templateTXT: parseEmbeddedTXT(embeddedFiles, "comms", file_txt),
}
}
return &result
}
func parseEmbeddedHTML(embeddedFiles embed.FS, subdir string, file string) *templatehtml.Template {
// Remap the file names to embedded paths
to_trim := subdir + "/"
embeddedFilePaths := []string{strings.TrimPrefix(file, to_trim)}
name := path.Base(embeddedFilePaths[0])
log.Debug().Str("name", name).Strs("paths", embeddedFilePaths).Msg("Parsing embedded template")
return templatehtml.Must(
templatehtml.New(name).ParseFS(embeddedFiles, embeddedFilePaths...))
}
func parseEmbeddedTXT(embeddedFiles embed.FS, subdir string, file string) *templatetxt.Template {
// Remap the file names to embedded paths
to_trim := subdir + "/"
embeddedFilePaths := []string{strings.TrimPrefix(file, to_trim)}
name := path.Base(embeddedFilePaths[0])
log.Debug().Str("name", name).Strs("paths", embeddedFilePaths).Msg("Parsing embedded template")
return templatetxt.Must(
templatetxt.New(name).ParseFS(embeddedFiles, embeddedFilePaths...))
}
func parseFromDiskHTML(file string) (*templatehtml.Template, error) {
name := path.Base(file)
//log.Debug().Str("name", name).Strs("files", files).Msg("parsing from disk")
templ, err := templatehtml.New(name).ParseFiles(file)
if err != nil {
return nil, fmt.Errorf("Failed to parse %s: %w", file, err)
}
return templ, nil
}
func parseFromDiskTXT(file string) (*templatetxt.Template, error) {
name := path.Base(file)
//log.Debug().Str("name", name).Strs("files", files).Msg("parsing from disk")
templ, err := templatetxt.New(name).ParseFiles(file)
if err != nil {
return nil, fmt.Errorf("Failed to parse %s: %w", file, err)
}
return templ, nil
}
func renderEmailTemplates(t *builtTemplate, content interface{}) (text string, html string, err error) {
buf_txt := &bytes.Buffer{}
err = t.executeTemplateTXT(buf_txt, content)
if err != nil {
return "", "", fmt.Errorf("Failed to render TXT template: %w", err)
}
buf_html := &bytes.Buffer{}
err = t.executeTemplateHTML(buf_html, content)
if err != nil {
return "", "", fmt.Errorf("Failed to render HTML template: %w", err)
}
return buf_txt.String(), buf_html.String(), nil
}

View file

@ -1 +0,0 @@
Welcome to Report Mosquitoes Online.

View file

@ -3,15 +3,15 @@
package dberrors
var CommsEmailErrors = &commsEmailErrors{
var CommsEmailContactErrors = &commsEmailContactErrors{
ErrUniqueEmailPkey: &UniqueConstraintError{
schema: "comms",
table: "email",
table: "email_contact",
columns: []string{"address"},
s: "email_pkey",
},
}
type commsEmailErrors struct {
type commsEmailContactErrors struct {
ErrUniqueEmailPkey *UniqueConstraintError
}

View file

@ -7,7 +7,7 @@ var CommsEmailLogErrors = &commsEmailLogErrors{
ErrUniqueEmailLogPkey: &UniqueConstraintError{
schema: "comms",
table: "email_log",
columns: []string{"destination", "source", "type"},
columns: []string{"id"},
s: "email_log_pkey",
},
}

View file

@ -0,0 +1,17 @@
// Code generated by BobGen psql v0.42.1. DO NOT EDIT.
// This file is meant to be re-generated in place and/or deleted at any time.
package dberrors
var CommsEmailTemplateErrors = &commsEmailTemplateErrors{
ErrUniqueEmailTemplatePkey: &UniqueConstraintError{
schema: "comms",
table: "email_template",
columns: []string{"id"},
s: "email_template_pkey",
},
}
type commsEmailTemplateErrors struct {
ErrUniqueEmailTemplatePkey *UniqueConstraintError
}

View file

@ -5,16 +5,16 @@ package dbinfo
import "github.com/aarondl/opt/null"
var CommsEmails = Table[
commsEmailColumns,
commsEmailIndexes,
commsEmailForeignKeys,
commsEmailUniques,
commsEmailChecks,
var CommsEmailContacts = Table[
commsEmailContactColumns,
commsEmailContactIndexes,
commsEmailContactForeignKeys,
commsEmailContactUniques,
commsEmailContactChecks,
]{
Schema: "comms",
Name: "email",
Columns: commsEmailColumns{
Name: "email_contact",
Columns: commsEmailContactColumns{
Address: column{
Name: "address",
DBType: "text",
@ -42,8 +42,17 @@ var CommsEmails = Table[
Generated: false,
AutoIncr: false,
},
PublicID: column{
Name: "public_id",
DBType: "text",
Default: "",
Comment: "",
Nullable: false,
Generated: false,
AutoIncr: false,
},
},
Indexes: commsEmailIndexes{
Indexes: commsEmailContactIndexes{
EmailPkey: index{
Type: "btree",
Name: "email_pkey",
@ -71,42 +80,43 @@ var CommsEmails = Table[
Comment: "",
}
type commsEmailColumns struct {
type commsEmailContactColumns struct {
Address column
Confirmed column
IsSubscribed column
PublicID column
}
func (c commsEmailColumns) AsSlice() []column {
func (c commsEmailContactColumns) AsSlice() []column {
return []column{
c.Address, c.Confirmed, c.IsSubscribed,
c.Address, c.Confirmed, c.IsSubscribed, c.PublicID,
}
}
type commsEmailIndexes struct {
type commsEmailContactIndexes struct {
EmailPkey index
}
func (i commsEmailIndexes) AsSlice() []index {
func (i commsEmailContactIndexes) AsSlice() []index {
return []index{
i.EmailPkey,
}
}
type commsEmailForeignKeys struct{}
type commsEmailContactForeignKeys struct{}
func (f commsEmailForeignKeys) AsSlice() []foreignKey {
func (f commsEmailContactForeignKeys) AsSlice() []foreignKey {
return []foreignKey{}
}
type commsEmailUniques struct{}
type commsEmailContactUniques struct{}
func (u commsEmailUniques) AsSlice() []constraint {
func (u commsEmailContactUniques) AsSlice() []constraint {
return []constraint{}
}
type commsEmailChecks struct{}
type commsEmailContactChecks struct{}
func (c commsEmailChecks) AsSlice() []check {
func (c commsEmailContactChecks) AsSlice() []check {
return []check{}
}

View file

@ -15,6 +15,15 @@ var CommsEmailLogs = Table[
Schema: "comms",
Name: "email_log",
Columns: commsEmailLogColumns{
ID: column{
Name: "id",
DBType: "integer",
Default: "nextval('comms.email_log_id_seq'::regclass)",
Comment: "",
Nullable: false,
Generated: false,
AutoIncr: false,
},
Created: column{
Name: "created",
DBType: "timestamp without time zone",
@ -24,6 +33,15 @@ var CommsEmailLogs = Table[
Generated: false,
AutoIncr: false,
},
DeliveryStatus: column{
Name: "delivery_status",
DBType: "character varying",
Default: "",
Comment: "",
Nullable: false,
Generated: false,
AutoIncr: false,
},
Destination: column{
Name: "destination",
DBType: "text",
@ -33,6 +51,24 @@ var CommsEmailLogs = Table[
Generated: false,
AutoIncr: false,
},
PublicID: column{
Name: "public_id",
DBType: "character varying",
Default: "",
Comment: "",
Nullable: false,
Generated: false,
AutoIncr: false,
},
SentAt: column{
Name: "sent_at",
DBType: "timestamp without time zone",
Default: "NULL",
Comment: "",
Nullable: true,
Generated: false,
AutoIncr: false,
},
Source: column{
Name: "source",
DBType: "text",
@ -42,6 +78,33 @@ var CommsEmailLogs = Table[
Generated: false,
AutoIncr: false,
},
Subject: column{
Name: "subject",
DBType: "character varying",
Default: "",
Comment: "",
Nullable: false,
Generated: false,
AutoIncr: false,
},
TemplateID: column{
Name: "template_id",
DBType: "integer",
Default: "NULL",
Comment: "",
Nullable: true,
Generated: false,
AutoIncr: false,
},
TemplateData: column{
Name: "template_data",
DBType: "hstore",
Default: "",
Comment: "",
Nullable: false,
Generated: false,
AutoIncr: false,
},
Type: column{
Name: "type",
DBType: "comms.messagetypeemail",
@ -58,24 +121,14 @@ var CommsEmailLogs = Table[
Name: "email_log_pkey",
Columns: []indexColumn{
{
Name: "destination",
Desc: null.FromCond(false, true),
IsExpression: false,
},
{
Name: "source",
Desc: null.FromCond(false, true),
IsExpression: false,
},
{
Name: "type",
Name: "id",
Desc: null.FromCond(false, true),
IsExpression: false,
},
},
Unique: true,
Comment: "",
NullsFirst: []bool{false, false, false},
NullsFirst: []bool{false},
NullsDistinct: false,
Where: "",
Include: []string{},
@ -83,7 +136,7 @@ var CommsEmailLogs = Table[
},
PrimaryKey: &constraint{
Name: "email_log_pkey",
Columns: []string{"destination", "source", "type"},
Columns: []string{"id"},
Comment: "",
},
ForeignKeys: commsEmailLogForeignKeys{
@ -93,17 +146,17 @@ var CommsEmailLogs = Table[
Columns: []string{"destination"},
Comment: "",
},
ForeignTable: "comms.email",
ForeignTable: "comms.email_contact",
ForeignColumns: []string{"address"},
},
CommsEmailLogEmailLogSourceFkey: foreignKey{
CommsEmailLogEmailLogTemplateIDFkey: foreignKey{
constraint: constraint{
Name: "comms.email_log.email_log_source_fkey",
Columns: []string{"source"},
Name: "comms.email_log.email_log_template_id_fkey",
Columns: []string{"template_id"},
Comment: "",
},
ForeignTable: "comms.phone",
ForeignColumns: []string{"e164"},
ForeignTable: "comms.email_template",
ForeignColumns: []string{"id"},
},
},
@ -111,15 +164,22 @@ var CommsEmailLogs = Table[
}
type commsEmailLogColumns struct {
Created column
Destination column
Source column
Type column
ID column
Created column
DeliveryStatus column
Destination column
PublicID column
SentAt column
Source column
Subject column
TemplateID column
TemplateData column
Type column
}
func (c commsEmailLogColumns) AsSlice() []column {
return []column{
c.Created, c.Destination, c.Source, c.Type,
c.ID, c.Created, c.DeliveryStatus, c.Destination, c.PublicID, c.SentAt, c.Source, c.Subject, c.TemplateID, c.TemplateData, c.Type,
}
}
@ -135,12 +195,12 @@ func (i commsEmailLogIndexes) AsSlice() []index {
type commsEmailLogForeignKeys struct {
CommsEmailLogEmailLogDestinationFkey foreignKey
CommsEmailLogEmailLogSourceFkey foreignKey
CommsEmailLogEmailLogTemplateIDFkey foreignKey
}
func (f commsEmailLogForeignKeys) AsSlice() []foreignKey {
return []foreignKey{
f.CommsEmailLogEmailLogDestinationFkey, f.CommsEmailLogEmailLogSourceFkey,
f.CommsEmailLogEmailLogDestinationFkey, f.CommsEmailLogEmailLogTemplateIDFkey,
}
}

View file

@ -0,0 +1,162 @@
// Code generated by BobGen psql v0.42.1. 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 CommsEmailTemplates = Table[
commsEmailTemplateColumns,
commsEmailTemplateIndexes,
commsEmailTemplateForeignKeys,
commsEmailTemplateUniques,
commsEmailTemplateChecks,
]{
Schema: "comms",
Name: "email_template",
Columns: commsEmailTemplateColumns{
ContentHTML: column{
Name: "content_html",
DBType: "text",
Default: "",
Comment: "",
Nullable: false,
Generated: false,
AutoIncr: false,
},
ContentTXT: column{
Name: "content_txt",
DBType: "text",
Default: "",
Comment: "",
Nullable: false,
Generated: false,
AutoIncr: false,
},
ContentHashHTML: column{
Name: "content_hash_html",
DBType: "character varying",
Default: "",
Comment: "",
Nullable: false,
Generated: false,
AutoIncr: false,
},
ContentHashTXT: column{
Name: "content_hash_txt",
DBType: "character varying",
Default: "",
Comment: "",
Nullable: false,
Generated: false,
AutoIncr: false,
},
Created: column{
Name: "created",
DBType: "timestamp without time zone",
Default: "",
Comment: "",
Nullable: false,
Generated: false,
AutoIncr: false,
},
ID: column{
Name: "id",
DBType: "integer",
Default: "nextval('comms.email_template_id_seq'::regclass)",
Comment: "",
Nullable: false,
Generated: false,
AutoIncr: false,
},
Superceded: column{
Name: "superceded",
DBType: "timestamp without time zone",
Default: "NULL",
Comment: "",
Nullable: true,
Generated: false,
AutoIncr: false,
},
MessageType: column{
Name: "message_type",
DBType: "comms.messagetypeemail",
Default: "",
Comment: "",
Nullable: false,
Generated: false,
AutoIncr: false,
},
},
Indexes: commsEmailTemplateIndexes{
EmailTemplatePkey: index{
Type: "btree",
Name: "email_template_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: "email_template_pkey",
Columns: []string{"id"},
Comment: "",
},
Comment: "",
}
type commsEmailTemplateColumns struct {
ContentHTML column
ContentTXT column
ContentHashHTML column
ContentHashTXT column
Created column
ID column
Superceded column
MessageType column
}
func (c commsEmailTemplateColumns) AsSlice() []column {
return []column{
c.ContentHTML, c.ContentTXT, c.ContentHashHTML, c.ContentHashTXT, c.Created, c.ID, c.Superceded, c.MessageType,
}
}
type commsEmailTemplateIndexes struct {
EmailTemplatePkey index
}
func (i commsEmailTemplateIndexes) AsSlice() []index {
return []index{
i.EmailTemplatePkey,
}
}
type commsEmailTemplateForeignKeys struct{}
func (f commsEmailTemplateForeignKeys) AsSlice() []foreignKey {
return []foreignKey{}
}
type commsEmailTemplateUniques struct{}
func (u commsEmailTemplateUniques) AsSlice() []constraint {
return []constraint{}
}
type commsEmailTemplateChecks struct{}
func (c commsEmailTemplateChecks) AsSlice() []check {
return []check{}
}

View file

@ -17,18 +17,21 @@ var (
arcgisUserPrivilegeWithParentsCascadingCtx = newContextual[bool]("arcgisUserPrivilegeWithParentsCascading")
arcgisUserPrivilegeRelUserUserCtx = newContextual[bool]("arcgis.user_.arcgis.user_privilege.arcgis.user_privilege.user_privilege_user_id_fkey")
// Relationship Contexts for comms.email
commsEmailWithParentsCascadingCtx = newContextual[bool]("commsEmailWithParentsCascading")
commsEmailRelDestinationEmailLogsCtx = newContextual[bool]("comms.email.comms.email_log.comms.email_log.email_log_destination_fkey")
// Relationship Contexts for comms.email_contact
commsEmailContactWithParentsCascadingCtx = newContextual[bool]("commsEmailContactWithParentsCascading")
commsEmailContactRelDestinationEmailLogsCtx = newContextual[bool]("comms.email_contact.comms.email_log.comms.email_log.email_log_destination_fkey")
// Relationship Contexts for comms.email_log
commsEmailLogWithParentsCascadingCtx = newContextual[bool]("commsEmailLogWithParentsCascading")
commsEmailLogRelDestinationEmailCtx = newContextual[bool]("comms.email.comms.email_log.comms.email_log.email_log_destination_fkey")
commsEmailLogRelSourcePhoneCtx = newContextual[bool]("comms.email_log.comms.phone.comms.email_log.email_log_source_fkey")
commsEmailLogWithParentsCascadingCtx = newContextual[bool]("commsEmailLogWithParentsCascading")
commsEmailLogRelDestinationEmailContactCtx = newContextual[bool]("comms.email_contact.comms.email_log.comms.email_log.email_log_destination_fkey")
commsEmailLogRelTemplateEmailTemplateCtx = newContextual[bool]("comms.email_log.comms.email_template.comms.email_log.email_log_template_id_fkey")
// Relationship Contexts for comms.email_template
commsEmailTemplateWithParentsCascadingCtx = newContextual[bool]("commsEmailTemplateWithParentsCascading")
commsEmailTemplateRelTemplateEmailLogsCtx = newContextual[bool]("comms.email_log.comms.email_template.comms.email_log.email_log_template_id_fkey")
// Relationship Contexts for comms.phone
commsPhoneWithParentsCascadingCtx = newContextual[bool]("commsPhoneWithParentsCascading")
commsPhoneRelSourceEmailLogsCtx = newContextual[bool]("comms.email_log.comms.phone.comms.email_log.email_log_source_fkey")
commsPhoneRelDestinationTextLogsCtx = newContextual[bool]("comms.phone.comms.text_log.comms.text_log.text_log_destination_fkey")
commsPhoneRelSourceTextLogsCtx = newContextual[bool]("comms.phone.comms.text_log.comms.text_log.text_log_source_fkey")

View file

@ -15,13 +15,15 @@ import (
"github.com/lib/pq"
"github.com/shopspring/decimal"
"github.com/stephenafamo/bob/types"
"github.com/stephenafamo/bob/types/pgtypes"
)
type Factory struct {
baseArcgisUserMods ArcgisUserModSlice
baseArcgisUserPrivilegeMods ArcgisUserPrivilegeModSlice
baseCommsEmailMods CommsEmailModSlice
baseCommsEmailContactMods CommsEmailContactModSlice
baseCommsEmailLogMods CommsEmailLogModSlice
baseCommsEmailTemplateMods CommsEmailTemplateModSlice
baseCommsPhoneMods CommsPhoneModSlice
baseCommsTextLogMods CommsTextLogModSlice
baseFieldseekerContainerrelateMods FieldseekerContainerrelateModSlice
@ -160,32 +162,33 @@ func (f *Factory) FromExistingArcgisUserPrivilege(m *models.ArcgisUserPrivilege)
return o
}
func (f *Factory) NewCommsEmail(mods ...CommsEmailMod) *CommsEmailTemplate {
return f.NewCommsEmailWithContext(context.Background(), mods...)
func (f *Factory) NewCommsEmailContact(mods ...CommsEmailContactMod) *CommsEmailContactTemplate {
return f.NewCommsEmailContactWithContext(context.Background(), mods...)
}
func (f *Factory) NewCommsEmailWithContext(ctx context.Context, mods ...CommsEmailMod) *CommsEmailTemplate {
o := &CommsEmailTemplate{f: f}
func (f *Factory) NewCommsEmailContactWithContext(ctx context.Context, mods ...CommsEmailContactMod) *CommsEmailContactTemplate {
o := &CommsEmailContactTemplate{f: f}
if f != nil {
f.baseCommsEmailMods.Apply(ctx, o)
f.baseCommsEmailContactMods.Apply(ctx, o)
}
CommsEmailModSlice(mods).Apply(ctx, o)
CommsEmailContactModSlice(mods).Apply(ctx, o)
return o
}
func (f *Factory) FromExistingCommsEmail(m *models.CommsEmail) *CommsEmailTemplate {
o := &CommsEmailTemplate{f: f, alreadyPersisted: true}
func (f *Factory) FromExistingCommsEmailContact(m *models.CommsEmailContact) *CommsEmailContactTemplate {
o := &CommsEmailContactTemplate{f: f, alreadyPersisted: true}
o.Address = func() string { return m.Address }
o.Confirmed = func() bool { return m.Confirmed }
o.IsSubscribed = func() bool { return m.IsSubscribed }
o.PublicID = func() string { return m.PublicID }
ctx := context.Background()
if len(m.R.DestinationEmailLogs) > 0 {
CommsEmailMods.AddExistingDestinationEmailLogs(m.R.DestinationEmailLogs...).Apply(ctx, o)
CommsEmailContactMods.AddExistingDestinationEmailLogs(m.R.DestinationEmailLogs...).Apply(ctx, o)
}
return o
@ -210,17 +213,60 @@ func (f *Factory) NewCommsEmailLogWithContext(ctx context.Context, mods ...Comms
func (f *Factory) FromExistingCommsEmailLog(m *models.CommsEmailLog) *CommsEmailLogTemplate {
o := &CommsEmailLogTemplate{f: f, alreadyPersisted: true}
o.ID = func() int32 { return m.ID }
o.Created = func() time.Time { return m.Created }
o.DeliveryStatus = func() string { return m.DeliveryStatus }
o.Destination = func() string { return m.Destination }
o.PublicID = func() string { return m.PublicID }
o.SentAt = func() null.Val[time.Time] { return m.SentAt }
o.Source = func() string { return m.Source }
o.Subject = func() string { return m.Subject }
o.TemplateID = func() null.Val[int32] { return m.TemplateID }
o.TemplateData = func() pgtypes.HStore { return m.TemplateData }
o.Type = func() enums.CommsMessagetypeemail { return m.Type }
ctx := context.Background()
if m.R.DestinationEmail != nil {
CommsEmailLogMods.WithExistingDestinationEmail(m.R.DestinationEmail).Apply(ctx, o)
if m.R.DestinationEmailContact != nil {
CommsEmailLogMods.WithExistingDestinationEmailContact(m.R.DestinationEmailContact).Apply(ctx, o)
}
if m.R.SourcePhone != nil {
CommsEmailLogMods.WithExistingSourcePhone(m.R.SourcePhone).Apply(ctx, o)
if m.R.TemplateEmailTemplate != nil {
CommsEmailLogMods.WithExistingTemplateEmailTemplate(m.R.TemplateEmailTemplate).Apply(ctx, o)
}
return o
}
func (f *Factory) NewCommsEmailTemplate(mods ...CommsEmailTemplateMod) *CommsEmailTemplateTemplate {
return f.NewCommsEmailTemplateWithContext(context.Background(), mods...)
}
func (f *Factory) NewCommsEmailTemplateWithContext(ctx context.Context, mods ...CommsEmailTemplateMod) *CommsEmailTemplateTemplate {
o := &CommsEmailTemplateTemplate{f: f}
if f != nil {
f.baseCommsEmailTemplateMods.Apply(ctx, o)
}
CommsEmailTemplateModSlice(mods).Apply(ctx, o)
return o
}
func (f *Factory) FromExistingCommsEmailTemplate(m *models.CommsEmailTemplate) *CommsEmailTemplateTemplate {
o := &CommsEmailTemplateTemplate{f: f, alreadyPersisted: true}
o.ContentHTML = func() string { return m.ContentHTML }
o.ContentTXT = func() string { return m.ContentTXT }
o.ContentHashHTML = func() string { return m.ContentHashHTML }
o.ContentHashTXT = func() string { return m.ContentHashTXT }
o.Created = func() time.Time { return m.Created }
o.ID = func() int32 { return m.ID }
o.Superceded = func() null.Val[time.Time] { return m.Superceded }
o.MessageType = func() enums.CommsMessagetypeemail { return m.MessageType }
ctx := context.Background()
if len(m.R.TemplateEmailLogs) > 0 {
CommsEmailTemplateMods.AddExistingTemplateEmailLogs(m.R.TemplateEmailLogs...).Apply(ctx, o)
}
return o
@ -249,9 +295,6 @@ func (f *Factory) FromExistingCommsPhone(m *models.CommsPhone) *CommsPhoneTempla
o.IsSubscribed = func() bool { return m.IsSubscribed }
ctx := context.Background()
if len(m.R.SourceEmailLogs) > 0 {
CommsPhoneMods.AddExistingSourceEmailLogs(m.R.SourceEmailLogs...).Apply(ctx, o)
}
if len(m.R.DestinationTextLogs) > 0 {
CommsPhoneMods.AddExistingDestinationTextLogs(m.R.DestinationTextLogs...).Apply(ctx, o)
}
@ -3198,12 +3241,12 @@ func (f *Factory) AddBaseArcgisUserPrivilegeMod(mods ...ArcgisUserPrivilegeMod)
f.baseArcgisUserPrivilegeMods = append(f.baseArcgisUserPrivilegeMods, mods...)
}
func (f *Factory) ClearBaseCommsEmailMods() {
f.baseCommsEmailMods = nil
func (f *Factory) ClearBaseCommsEmailContactMods() {
f.baseCommsEmailContactMods = nil
}
func (f *Factory) AddBaseCommsEmailMod(mods ...CommsEmailMod) {
f.baseCommsEmailMods = append(f.baseCommsEmailMods, mods...)
func (f *Factory) AddBaseCommsEmailContactMod(mods ...CommsEmailContactMod) {
f.baseCommsEmailContactMods = append(f.baseCommsEmailContactMods, mods...)
}
func (f *Factory) ClearBaseCommsEmailLogMods() {
@ -3214,6 +3257,14 @@ func (f *Factory) AddBaseCommsEmailLogMod(mods ...CommsEmailLogMod) {
f.baseCommsEmailLogMods = append(f.baseCommsEmailLogMods, mods...)
}
func (f *Factory) ClearBaseCommsEmailTemplateMods() {
f.baseCommsEmailTemplateMods = nil
}
func (f *Factory) AddBaseCommsEmailTemplateMod(mods ...CommsEmailTemplateMod) {
f.baseCommsEmailTemplateMods = append(f.baseCommsEmailTemplateMods, mods...)
}
func (f *Factory) ClearBaseCommsPhoneMods() {
f.baseCommsPhoneMods = nil
}

View file

@ -5,6 +5,7 @@ package factory
import (
"bytes"
"database/sql"
"encoding/json"
"fmt"
"math"
@ -18,6 +19,7 @@ import (
"github.com/lib/pq"
"github.com/shopspring/decimal"
"github.com/stephenafamo/bob/types"
"github.com/stephenafamo/bob/types/pgtypes"
)
var defaultFaker = faker.New()
@ -281,6 +283,18 @@ func random_int64(f *faker.Faker, limits ...string) int64 {
return f.Int64()
}
func random_pgtypes_HStore(f *faker.Faker, limits ...string) pgtypes.HStore {
if f == nil {
f = &defaultFaker
}
hs := make(pgtypes.HStore)
for range f.IntBetween(1, 5) {
hs[random_string(f)] = sql.Null[string]{V: random_string(f, limits...), Valid: f.Bool()}
}
return hs
}
func random_pq_BoolArray(f *faker.Faker, limits ...string) pq.BoolArray {
if f == nil {
f = &defaultFaker

View file

@ -1,434 +0,0 @@
// Code generated by BobGen psql v0.42.1. DO NOT EDIT.
// This file is meant to be re-generated in place and/or deleted at any time.
package factory
import (
"context"
"testing"
models "github.com/Gleipnir-Technology/nidus-sync/db/models"
"github.com/aarondl/opt/omit"
"github.com/jaswdr/faker/v2"
"github.com/stephenafamo/bob"
)
type CommsEmailMod interface {
Apply(context.Context, *CommsEmailTemplate)
}
type CommsEmailModFunc func(context.Context, *CommsEmailTemplate)
func (f CommsEmailModFunc) Apply(ctx context.Context, n *CommsEmailTemplate) {
f(ctx, n)
}
type CommsEmailModSlice []CommsEmailMod
func (mods CommsEmailModSlice) Apply(ctx context.Context, n *CommsEmailTemplate) {
for _, f := range mods {
f.Apply(ctx, n)
}
}
// CommsEmailTemplate is an object representing the database table.
// all columns are optional and should be set by mods
type CommsEmailTemplate struct {
Address func() string
Confirmed func() bool
IsSubscribed func() bool
r commsEmailR
f *Factory
alreadyPersisted bool
}
type commsEmailR struct {
DestinationEmailLogs []*commsEmailRDestinationEmailLogsR
}
type commsEmailRDestinationEmailLogsR struct {
number int
o *CommsEmailLogTemplate
}
// Apply mods to the CommsEmailTemplate
func (o *CommsEmailTemplate) Apply(ctx context.Context, mods ...CommsEmailMod) {
for _, mod := range mods {
mod.Apply(ctx, o)
}
}
// setModelRels creates and sets the relationships on *models.CommsEmail
// according to the relationships in the template. Nothing is inserted into the db
func (t CommsEmailTemplate) setModelRels(o *models.CommsEmail) {
if t.r.DestinationEmailLogs != nil {
rel := models.CommsEmailLogSlice{}
for _, r := range t.r.DestinationEmailLogs {
related := r.o.BuildMany(r.number)
for _, rel := range related {
rel.Destination = o.Address // h2
rel.R.DestinationEmail = o
}
rel = append(rel, related...)
}
o.R.DestinationEmailLogs = rel
}
}
// BuildSetter returns an *models.CommsEmailSetter
// this does nothing with the relationship templates
func (o CommsEmailTemplate) BuildSetter() *models.CommsEmailSetter {
m := &models.CommsEmailSetter{}
if o.Address != nil {
val := o.Address()
m.Address = omit.From(val)
}
if o.Confirmed != nil {
val := o.Confirmed()
m.Confirmed = omit.From(val)
}
if o.IsSubscribed != nil {
val := o.IsSubscribed()
m.IsSubscribed = omit.From(val)
}
return m
}
// BuildManySetter returns an []*models.CommsEmailSetter
// this does nothing with the relationship templates
func (o CommsEmailTemplate) BuildManySetter(number int) []*models.CommsEmailSetter {
m := make([]*models.CommsEmailSetter, number)
for i := range m {
m[i] = o.BuildSetter()
}
return m
}
// Build returns an *models.CommsEmail
// Related objects are also created and placed in the .R field
// NOTE: Objects are not inserted into the database. Use CommsEmailTemplate.Create
func (o CommsEmailTemplate) Build() *models.CommsEmail {
m := &models.CommsEmail{}
if o.Address != nil {
m.Address = o.Address()
}
if o.Confirmed != nil {
m.Confirmed = o.Confirmed()
}
if o.IsSubscribed != nil {
m.IsSubscribed = o.IsSubscribed()
}
o.setModelRels(m)
return m
}
// BuildMany returns an models.CommsEmailSlice
// Related objects are also created and placed in the .R field
// NOTE: Objects are not inserted into the database. Use CommsEmailTemplate.CreateMany
func (o CommsEmailTemplate) BuildMany(number int) models.CommsEmailSlice {
m := make(models.CommsEmailSlice, number)
for i := range m {
m[i] = o.Build()
}
return m
}
func ensureCreatableCommsEmail(m *models.CommsEmailSetter) {
if !(m.Address.IsValue()) {
val := random_string(nil)
m.Address = omit.From(val)
}
if !(m.Confirmed.IsValue()) {
val := random_bool(nil)
m.Confirmed = omit.From(val)
}
if !(m.IsSubscribed.IsValue()) {
val := random_bool(nil)
m.IsSubscribed = omit.From(val)
}
}
// insertOptRels creates and inserts any optional the relationships on *models.CommsEmail
// according to the relationships in the template.
// any required relationship should have already exist on the model
func (o *CommsEmailTemplate) insertOptRels(ctx context.Context, exec bob.Executor, m *models.CommsEmail) error {
var err error
isDestinationEmailLogsDone, _ := commsEmailRelDestinationEmailLogsCtx.Value(ctx)
if !isDestinationEmailLogsDone && o.r.DestinationEmailLogs != nil {
ctx = commsEmailRelDestinationEmailLogsCtx.WithValue(ctx, true)
for _, r := range o.r.DestinationEmailLogs {
if r.o.alreadyPersisted {
m.R.DestinationEmailLogs = append(m.R.DestinationEmailLogs, r.o.Build())
} else {
rel0, err := r.o.CreateMany(ctx, exec, r.number)
if err != nil {
return err
}
err = m.AttachDestinationEmailLogs(ctx, exec, rel0...)
if err != nil {
return err
}
}
}
}
return err
}
// Create builds a commsEmail and inserts it into the database
// Relations objects are also inserted and placed in the .R field
func (o *CommsEmailTemplate) Create(ctx context.Context, exec bob.Executor) (*models.CommsEmail, error) {
var err error
opt := o.BuildSetter()
ensureCreatableCommsEmail(opt)
m, err := models.CommsEmails.Insert(opt).One(ctx, exec)
if err != nil {
return nil, err
}
if err := o.insertOptRels(ctx, exec, m); err != nil {
return nil, err
}
return m, err
}
// MustCreate builds a commsEmail and inserts it into the database
// Relations objects are also inserted and placed in the .R field
// panics if an error occurs
func (o *CommsEmailTemplate) MustCreate(ctx context.Context, exec bob.Executor) *models.CommsEmail {
m, err := o.Create(ctx, exec)
if err != nil {
panic(err)
}
return m
}
// CreateOrFail builds a commsEmail and inserts it into the database
// Relations objects are also inserted and placed in the .R field
// It calls `tb.Fatal(err)` on the test/benchmark if an error occurs
func (o *CommsEmailTemplate) CreateOrFail(ctx context.Context, tb testing.TB, exec bob.Executor) *models.CommsEmail {
tb.Helper()
m, err := o.Create(ctx, exec)
if err != nil {
tb.Fatal(err)
return nil
}
return m
}
// CreateMany builds multiple commsEmails and inserts them into the database
// Relations objects are also inserted and placed in the .R field
func (o CommsEmailTemplate) CreateMany(ctx context.Context, exec bob.Executor, number int) (models.CommsEmailSlice, error) {
var err error
m := make(models.CommsEmailSlice, number)
for i := range m {
m[i], err = o.Create(ctx, exec)
if err != nil {
return nil, err
}
}
return m, nil
}
// MustCreateMany builds multiple commsEmails and inserts them into the database
// Relations objects are also inserted and placed in the .R field
// panics if an error occurs
func (o CommsEmailTemplate) MustCreateMany(ctx context.Context, exec bob.Executor, number int) models.CommsEmailSlice {
m, err := o.CreateMany(ctx, exec, number)
if err != nil {
panic(err)
}
return m
}
// CreateManyOrFail builds multiple commsEmails and inserts them into the database
// Relations objects are also inserted and placed in the .R field
// It calls `tb.Fatal(err)` on the test/benchmark if an error occurs
func (o CommsEmailTemplate) CreateManyOrFail(ctx context.Context, tb testing.TB, exec bob.Executor, number int) models.CommsEmailSlice {
tb.Helper()
m, err := o.CreateMany(ctx, exec, number)
if err != nil {
tb.Fatal(err)
return nil
}
return m
}
// CommsEmail has methods that act as mods for the CommsEmailTemplate
var CommsEmailMods commsEmailMods
type commsEmailMods struct{}
func (m commsEmailMods) RandomizeAllColumns(f *faker.Faker) CommsEmailMod {
return CommsEmailModSlice{
CommsEmailMods.RandomAddress(f),
CommsEmailMods.RandomConfirmed(f),
CommsEmailMods.RandomIsSubscribed(f),
}
}
// Set the model columns to this value
func (m commsEmailMods) Address(val string) CommsEmailMod {
return CommsEmailModFunc(func(_ context.Context, o *CommsEmailTemplate) {
o.Address = func() string { return val }
})
}
// Set the Column from the function
func (m commsEmailMods) AddressFunc(f func() string) CommsEmailMod {
return CommsEmailModFunc(func(_ context.Context, o *CommsEmailTemplate) {
o.Address = f
})
}
// Clear any values for the column
func (m commsEmailMods) UnsetAddress() CommsEmailMod {
return CommsEmailModFunc(func(_ context.Context, o *CommsEmailTemplate) {
o.Address = nil
})
}
// Generates a random value for the column using the given faker
// if faker is nil, a default faker is used
func (m commsEmailMods) RandomAddress(f *faker.Faker) CommsEmailMod {
return CommsEmailModFunc(func(_ context.Context, o *CommsEmailTemplate) {
o.Address = func() string {
return random_string(f)
}
})
}
// Set the model columns to this value
func (m commsEmailMods) Confirmed(val bool) CommsEmailMod {
return CommsEmailModFunc(func(_ context.Context, o *CommsEmailTemplate) {
o.Confirmed = func() bool { return val }
})
}
// Set the Column from the function
func (m commsEmailMods) ConfirmedFunc(f func() bool) CommsEmailMod {
return CommsEmailModFunc(func(_ context.Context, o *CommsEmailTemplate) {
o.Confirmed = f
})
}
// Clear any values for the column
func (m commsEmailMods) UnsetConfirmed() CommsEmailMod {
return CommsEmailModFunc(func(_ context.Context, o *CommsEmailTemplate) {
o.Confirmed = nil
})
}
// Generates a random value for the column using the given faker
// if faker is nil, a default faker is used
func (m commsEmailMods) RandomConfirmed(f *faker.Faker) CommsEmailMod {
return CommsEmailModFunc(func(_ context.Context, o *CommsEmailTemplate) {
o.Confirmed = func() bool {
return random_bool(f)
}
})
}
// Set the model columns to this value
func (m commsEmailMods) IsSubscribed(val bool) CommsEmailMod {
return CommsEmailModFunc(func(_ context.Context, o *CommsEmailTemplate) {
o.IsSubscribed = func() bool { return val }
})
}
// Set the Column from the function
func (m commsEmailMods) IsSubscribedFunc(f func() bool) CommsEmailMod {
return CommsEmailModFunc(func(_ context.Context, o *CommsEmailTemplate) {
o.IsSubscribed = f
})
}
// Clear any values for the column
func (m commsEmailMods) UnsetIsSubscribed() CommsEmailMod {
return CommsEmailModFunc(func(_ context.Context, o *CommsEmailTemplate) {
o.IsSubscribed = nil
})
}
// Generates a random value for the column using the given faker
// if faker is nil, a default faker is used
func (m commsEmailMods) RandomIsSubscribed(f *faker.Faker) CommsEmailMod {
return CommsEmailModFunc(func(_ context.Context, o *CommsEmailTemplate) {
o.IsSubscribed = func() bool {
return random_bool(f)
}
})
}
func (m commsEmailMods) WithParentsCascading() CommsEmailMod {
return CommsEmailModFunc(func(ctx context.Context, o *CommsEmailTemplate) {
if isDone, _ := commsEmailWithParentsCascadingCtx.Value(ctx); isDone {
return
}
ctx = commsEmailWithParentsCascadingCtx.WithValue(ctx, true)
})
}
func (m commsEmailMods) WithDestinationEmailLogs(number int, related *CommsEmailLogTemplate) CommsEmailMod {
return CommsEmailModFunc(func(ctx context.Context, o *CommsEmailTemplate) {
o.r.DestinationEmailLogs = []*commsEmailRDestinationEmailLogsR{{
number: number,
o: related,
}}
})
}
func (m commsEmailMods) WithNewDestinationEmailLogs(number int, mods ...CommsEmailLogMod) CommsEmailMod {
return CommsEmailModFunc(func(ctx context.Context, o *CommsEmailTemplate) {
related := o.f.NewCommsEmailLogWithContext(ctx, mods...)
m.WithDestinationEmailLogs(number, related).Apply(ctx, o)
})
}
func (m commsEmailMods) AddDestinationEmailLogs(number int, related *CommsEmailLogTemplate) CommsEmailMod {
return CommsEmailModFunc(func(ctx context.Context, o *CommsEmailTemplate) {
o.r.DestinationEmailLogs = append(o.r.DestinationEmailLogs, &commsEmailRDestinationEmailLogsR{
number: number,
o: related,
})
})
}
func (m commsEmailMods) AddNewDestinationEmailLogs(number int, mods ...CommsEmailLogMod) CommsEmailMod {
return CommsEmailModFunc(func(ctx context.Context, o *CommsEmailTemplate) {
related := o.f.NewCommsEmailLogWithContext(ctx, mods...)
m.AddDestinationEmailLogs(number, related).Apply(ctx, o)
})
}
func (m commsEmailMods) AddExistingDestinationEmailLogs(existingModels ...*models.CommsEmailLog) CommsEmailMod {
return CommsEmailModFunc(func(ctx context.Context, o *CommsEmailTemplate) {
for _, em := range existingModels {
o.r.DestinationEmailLogs = append(o.r.DestinationEmailLogs, &commsEmailRDestinationEmailLogsR{
o: o.f.FromExistingCommsEmailLog(em),
})
}
})
}
func (m commsEmailMods) WithoutDestinationEmailLogs() CommsEmailMod {
return CommsEmailModFunc(func(ctx context.Context, o *CommsEmailTemplate) {
o.r.DestinationEmailLogs = nil
})
}

View file

@ -0,0 +1,478 @@
// Code generated by BobGen psql v0.42.1. DO NOT EDIT.
// This file is meant to be re-generated in place and/or deleted at any time.
package factory
import (
"context"
"testing"
models "github.com/Gleipnir-Technology/nidus-sync/db/models"
"github.com/aarondl/opt/omit"
"github.com/jaswdr/faker/v2"
"github.com/stephenafamo/bob"
)
type CommsEmailContactMod interface {
Apply(context.Context, *CommsEmailContactTemplate)
}
type CommsEmailContactModFunc func(context.Context, *CommsEmailContactTemplate)
func (f CommsEmailContactModFunc) Apply(ctx context.Context, n *CommsEmailContactTemplate) {
f(ctx, n)
}
type CommsEmailContactModSlice []CommsEmailContactMod
func (mods CommsEmailContactModSlice) Apply(ctx context.Context, n *CommsEmailContactTemplate) {
for _, f := range mods {
f.Apply(ctx, n)
}
}
// CommsEmailContactTemplate is an object representing the database table.
// all columns are optional and should be set by mods
type CommsEmailContactTemplate struct {
Address func() string
Confirmed func() bool
IsSubscribed func() bool
PublicID func() string
r commsEmailContactR
f *Factory
alreadyPersisted bool
}
type commsEmailContactR struct {
DestinationEmailLogs []*commsEmailContactRDestinationEmailLogsR
}
type commsEmailContactRDestinationEmailLogsR struct {
number int
o *CommsEmailLogTemplate
}
// Apply mods to the CommsEmailContactTemplate
func (o *CommsEmailContactTemplate) Apply(ctx context.Context, mods ...CommsEmailContactMod) {
for _, mod := range mods {
mod.Apply(ctx, o)
}
}
// setModelRels creates and sets the relationships on *models.CommsEmailContact
// according to the relationships in the template. Nothing is inserted into the db
func (t CommsEmailContactTemplate) setModelRels(o *models.CommsEmailContact) {
if t.r.DestinationEmailLogs != nil {
rel := models.CommsEmailLogSlice{}
for _, r := range t.r.DestinationEmailLogs {
related := r.o.BuildMany(r.number)
for _, rel := range related {
rel.Destination = o.Address // h2
rel.R.DestinationEmailContact = o
}
rel = append(rel, related...)
}
o.R.DestinationEmailLogs = rel
}
}
// BuildSetter returns an *models.CommsEmailContactSetter
// this does nothing with the relationship templates
func (o CommsEmailContactTemplate) BuildSetter() *models.CommsEmailContactSetter {
m := &models.CommsEmailContactSetter{}
if o.Address != nil {
val := o.Address()
m.Address = omit.From(val)
}
if o.Confirmed != nil {
val := o.Confirmed()
m.Confirmed = omit.From(val)
}
if o.IsSubscribed != nil {
val := o.IsSubscribed()
m.IsSubscribed = omit.From(val)
}
if o.PublicID != nil {
val := o.PublicID()
m.PublicID = omit.From(val)
}
return m
}
// BuildManySetter returns an []*models.CommsEmailContactSetter
// this does nothing with the relationship templates
func (o CommsEmailContactTemplate) BuildManySetter(number int) []*models.CommsEmailContactSetter {
m := make([]*models.CommsEmailContactSetter, number)
for i := range m {
m[i] = o.BuildSetter()
}
return m
}
// Build returns an *models.CommsEmailContact
// Related objects are also created and placed in the .R field
// NOTE: Objects are not inserted into the database. Use CommsEmailContactTemplate.Create
func (o CommsEmailContactTemplate) Build() *models.CommsEmailContact {
m := &models.CommsEmailContact{}
if o.Address != nil {
m.Address = o.Address()
}
if o.Confirmed != nil {
m.Confirmed = o.Confirmed()
}
if o.IsSubscribed != nil {
m.IsSubscribed = o.IsSubscribed()
}
if o.PublicID != nil {
m.PublicID = o.PublicID()
}
o.setModelRels(m)
return m
}
// BuildMany returns an models.CommsEmailContactSlice
// Related objects are also created and placed in the .R field
// NOTE: Objects are not inserted into the database. Use CommsEmailContactTemplate.CreateMany
func (o CommsEmailContactTemplate) BuildMany(number int) models.CommsEmailContactSlice {
m := make(models.CommsEmailContactSlice, number)
for i := range m {
m[i] = o.Build()
}
return m
}
func ensureCreatableCommsEmailContact(m *models.CommsEmailContactSetter) {
if !(m.Address.IsValue()) {
val := random_string(nil)
m.Address = omit.From(val)
}
if !(m.Confirmed.IsValue()) {
val := random_bool(nil)
m.Confirmed = omit.From(val)
}
if !(m.IsSubscribed.IsValue()) {
val := random_bool(nil)
m.IsSubscribed = omit.From(val)
}
if !(m.PublicID.IsValue()) {
val := random_string(nil)
m.PublicID = omit.From(val)
}
}
// insertOptRels creates and inserts any optional the relationships on *models.CommsEmailContact
// according to the relationships in the template.
// any required relationship should have already exist on the model
func (o *CommsEmailContactTemplate) insertOptRels(ctx context.Context, exec bob.Executor, m *models.CommsEmailContact) error {
var err error
isDestinationEmailLogsDone, _ := commsEmailContactRelDestinationEmailLogsCtx.Value(ctx)
if !isDestinationEmailLogsDone && o.r.DestinationEmailLogs != nil {
ctx = commsEmailContactRelDestinationEmailLogsCtx.WithValue(ctx, true)
for _, r := range o.r.DestinationEmailLogs {
if r.o.alreadyPersisted {
m.R.DestinationEmailLogs = append(m.R.DestinationEmailLogs, r.o.Build())
} else {
rel0, err := r.o.CreateMany(ctx, exec, r.number)
if err != nil {
return err
}
err = m.AttachDestinationEmailLogs(ctx, exec, rel0...)
if err != nil {
return err
}
}
}
}
return err
}
// Create builds a commsEmailContact and inserts it into the database
// Relations objects are also inserted and placed in the .R field
func (o *CommsEmailContactTemplate) Create(ctx context.Context, exec bob.Executor) (*models.CommsEmailContact, error) {
var err error
opt := o.BuildSetter()
ensureCreatableCommsEmailContact(opt)
m, err := models.CommsEmailContacts.Insert(opt).One(ctx, exec)
if err != nil {
return nil, err
}
if err := o.insertOptRels(ctx, exec, m); err != nil {
return nil, err
}
return m, err
}
// MustCreate builds a commsEmailContact and inserts it into the database
// Relations objects are also inserted and placed in the .R field
// panics if an error occurs
func (o *CommsEmailContactTemplate) MustCreate(ctx context.Context, exec bob.Executor) *models.CommsEmailContact {
m, err := o.Create(ctx, exec)
if err != nil {
panic(err)
}
return m
}
// CreateOrFail builds a commsEmailContact and inserts it into the database
// Relations objects are also inserted and placed in the .R field
// It calls `tb.Fatal(err)` on the test/benchmark if an error occurs
func (o *CommsEmailContactTemplate) CreateOrFail(ctx context.Context, tb testing.TB, exec bob.Executor) *models.CommsEmailContact {
tb.Helper()
m, err := o.Create(ctx, exec)
if err != nil {
tb.Fatal(err)
return nil
}
return m
}
// CreateMany builds multiple commsEmailContacts and inserts them into the database
// Relations objects are also inserted and placed in the .R field
func (o CommsEmailContactTemplate) CreateMany(ctx context.Context, exec bob.Executor, number int) (models.CommsEmailContactSlice, error) {
var err error
m := make(models.CommsEmailContactSlice, number)
for i := range m {
m[i], err = o.Create(ctx, exec)
if err != nil {
return nil, err
}
}
return m, nil
}
// MustCreateMany builds multiple commsEmailContacts and inserts them into the database
// Relations objects are also inserted and placed in the .R field
// panics if an error occurs
func (o CommsEmailContactTemplate) MustCreateMany(ctx context.Context, exec bob.Executor, number int) models.CommsEmailContactSlice {
m, err := o.CreateMany(ctx, exec, number)
if err != nil {
panic(err)
}
return m
}
// CreateManyOrFail builds multiple commsEmailContacts and inserts them into the database
// Relations objects are also inserted and placed in the .R field
// It calls `tb.Fatal(err)` on the test/benchmark if an error occurs
func (o CommsEmailContactTemplate) CreateManyOrFail(ctx context.Context, tb testing.TB, exec bob.Executor, number int) models.CommsEmailContactSlice {
tb.Helper()
m, err := o.CreateMany(ctx, exec, number)
if err != nil {
tb.Fatal(err)
return nil
}
return m
}
// CommsEmailContact has methods that act as mods for the CommsEmailContactTemplate
var CommsEmailContactMods commsEmailContactMods
type commsEmailContactMods struct{}
func (m commsEmailContactMods) RandomizeAllColumns(f *faker.Faker) CommsEmailContactMod {
return CommsEmailContactModSlice{
CommsEmailContactMods.RandomAddress(f),
CommsEmailContactMods.RandomConfirmed(f),
CommsEmailContactMods.RandomIsSubscribed(f),
CommsEmailContactMods.RandomPublicID(f),
}
}
// Set the model columns to this value
func (m commsEmailContactMods) Address(val string) CommsEmailContactMod {
return CommsEmailContactModFunc(func(_ context.Context, o *CommsEmailContactTemplate) {
o.Address = func() string { return val }
})
}
// Set the Column from the function
func (m commsEmailContactMods) AddressFunc(f func() string) CommsEmailContactMod {
return CommsEmailContactModFunc(func(_ context.Context, o *CommsEmailContactTemplate) {
o.Address = f
})
}
// Clear any values for the column
func (m commsEmailContactMods) UnsetAddress() CommsEmailContactMod {
return CommsEmailContactModFunc(func(_ context.Context, o *CommsEmailContactTemplate) {
o.Address = nil
})
}
// Generates a random value for the column using the given faker
// if faker is nil, a default faker is used
func (m commsEmailContactMods) RandomAddress(f *faker.Faker) CommsEmailContactMod {
return CommsEmailContactModFunc(func(_ context.Context, o *CommsEmailContactTemplate) {
o.Address = func() string {
return random_string(f)
}
})
}
// Set the model columns to this value
func (m commsEmailContactMods) Confirmed(val bool) CommsEmailContactMod {
return CommsEmailContactModFunc(func(_ context.Context, o *CommsEmailContactTemplate) {
o.Confirmed = func() bool { return val }
})
}
// Set the Column from the function
func (m commsEmailContactMods) ConfirmedFunc(f func() bool) CommsEmailContactMod {
return CommsEmailContactModFunc(func(_ context.Context, o *CommsEmailContactTemplate) {
o.Confirmed = f
})
}
// Clear any values for the column
func (m commsEmailContactMods) UnsetConfirmed() CommsEmailContactMod {
return CommsEmailContactModFunc(func(_ context.Context, o *CommsEmailContactTemplate) {
o.Confirmed = nil
})
}
// Generates a random value for the column using the given faker
// if faker is nil, a default faker is used
func (m commsEmailContactMods) RandomConfirmed(f *faker.Faker) CommsEmailContactMod {
return CommsEmailContactModFunc(func(_ context.Context, o *CommsEmailContactTemplate) {
o.Confirmed = func() bool {
return random_bool(f)
}
})
}
// Set the model columns to this value
func (m commsEmailContactMods) IsSubscribed(val bool) CommsEmailContactMod {
return CommsEmailContactModFunc(func(_ context.Context, o *CommsEmailContactTemplate) {
o.IsSubscribed = func() bool { return val }
})
}
// Set the Column from the function
func (m commsEmailContactMods) IsSubscribedFunc(f func() bool) CommsEmailContactMod {
return CommsEmailContactModFunc(func(_ context.Context, o *CommsEmailContactTemplate) {
o.IsSubscribed = f
})
}
// Clear any values for the column
func (m commsEmailContactMods) UnsetIsSubscribed() CommsEmailContactMod {
return CommsEmailContactModFunc(func(_ context.Context, o *CommsEmailContactTemplate) {
o.IsSubscribed = nil
})
}
// Generates a random value for the column using the given faker
// if faker is nil, a default faker is used
func (m commsEmailContactMods) RandomIsSubscribed(f *faker.Faker) CommsEmailContactMod {
return CommsEmailContactModFunc(func(_ context.Context, o *CommsEmailContactTemplate) {
o.IsSubscribed = func() bool {
return random_bool(f)
}
})
}
// Set the model columns to this value
func (m commsEmailContactMods) PublicID(val string) CommsEmailContactMod {
return CommsEmailContactModFunc(func(_ context.Context, o *CommsEmailContactTemplate) {
o.PublicID = func() string { return val }
})
}
// Set the Column from the function
func (m commsEmailContactMods) PublicIDFunc(f func() string) CommsEmailContactMod {
return CommsEmailContactModFunc(func(_ context.Context, o *CommsEmailContactTemplate) {
o.PublicID = f
})
}
// Clear any values for the column
func (m commsEmailContactMods) UnsetPublicID() CommsEmailContactMod {
return CommsEmailContactModFunc(func(_ context.Context, o *CommsEmailContactTemplate) {
o.PublicID = nil
})
}
// Generates a random value for the column using the given faker
// if faker is nil, a default faker is used
func (m commsEmailContactMods) RandomPublicID(f *faker.Faker) CommsEmailContactMod {
return CommsEmailContactModFunc(func(_ context.Context, o *CommsEmailContactTemplate) {
o.PublicID = func() string {
return random_string(f)
}
})
}
func (m commsEmailContactMods) WithParentsCascading() CommsEmailContactMod {
return CommsEmailContactModFunc(func(ctx context.Context, o *CommsEmailContactTemplate) {
if isDone, _ := commsEmailContactWithParentsCascadingCtx.Value(ctx); isDone {
return
}
ctx = commsEmailContactWithParentsCascadingCtx.WithValue(ctx, true)
})
}
func (m commsEmailContactMods) WithDestinationEmailLogs(number int, related *CommsEmailLogTemplate) CommsEmailContactMod {
return CommsEmailContactModFunc(func(ctx context.Context, o *CommsEmailContactTemplate) {
o.r.DestinationEmailLogs = []*commsEmailContactRDestinationEmailLogsR{{
number: number,
o: related,
}}
})
}
func (m commsEmailContactMods) WithNewDestinationEmailLogs(number int, mods ...CommsEmailLogMod) CommsEmailContactMod {
return CommsEmailContactModFunc(func(ctx context.Context, o *CommsEmailContactTemplate) {
related := o.f.NewCommsEmailLogWithContext(ctx, mods...)
m.WithDestinationEmailLogs(number, related).Apply(ctx, o)
})
}
func (m commsEmailContactMods) AddDestinationEmailLogs(number int, related *CommsEmailLogTemplate) CommsEmailContactMod {
return CommsEmailContactModFunc(func(ctx context.Context, o *CommsEmailContactTemplate) {
o.r.DestinationEmailLogs = append(o.r.DestinationEmailLogs, &commsEmailContactRDestinationEmailLogsR{
number: number,
o: related,
})
})
}
func (m commsEmailContactMods) AddNewDestinationEmailLogs(number int, mods ...CommsEmailLogMod) CommsEmailContactMod {
return CommsEmailContactModFunc(func(ctx context.Context, o *CommsEmailContactTemplate) {
related := o.f.NewCommsEmailLogWithContext(ctx, mods...)
m.AddDestinationEmailLogs(number, related).Apply(ctx, o)
})
}
func (m commsEmailContactMods) AddExistingDestinationEmailLogs(existingModels ...*models.CommsEmailLog) CommsEmailContactMod {
return CommsEmailContactModFunc(func(ctx context.Context, o *CommsEmailContactTemplate) {
for _, em := range existingModels {
o.r.DestinationEmailLogs = append(o.r.DestinationEmailLogs, &commsEmailContactRDestinationEmailLogsR{
o: o.f.FromExistingCommsEmailLog(em),
})
}
})
}
func (m commsEmailContactMods) WithoutDestinationEmailLogs() CommsEmailContactMod {
return CommsEmailContactModFunc(func(ctx context.Context, o *CommsEmailContactTemplate) {
o.r.DestinationEmailLogs = nil
})
}

View file

@ -10,9 +10,12 @@ import (
enums "github.com/Gleipnir-Technology/nidus-sync/db/enums"
models "github.com/Gleipnir-Technology/nidus-sync/db/models"
"github.com/aarondl/opt/null"
"github.com/aarondl/opt/omit"
"github.com/aarondl/opt/omitnull"
"github.com/jaswdr/faker/v2"
"github.com/stephenafamo/bob"
"github.com/stephenafamo/bob/types/pgtypes"
)
type CommsEmailLogMod interface {
@ -36,10 +39,17 @@ func (mods CommsEmailLogModSlice) Apply(ctx context.Context, n *CommsEmailLogTem
// CommsEmailLogTemplate is an object representing the database table.
// all columns are optional and should be set by mods
type CommsEmailLogTemplate struct {
Created func() time.Time
Destination func() string
Source func() string
Type func() enums.CommsMessagetypeemail
ID func() int32
Created func() time.Time
DeliveryStatus func() string
Destination func() string
PublicID func() string
SentAt func() null.Val[time.Time]
Source func() string
Subject func() string
TemplateID func() null.Val[int32]
TemplateData func() pgtypes.HStore
Type func() enums.CommsMessagetypeemail
r commsEmailLogR
f *Factory
@ -48,15 +58,15 @@ type CommsEmailLogTemplate struct {
}
type commsEmailLogR struct {
DestinationEmail *commsEmailLogRDestinationEmailR
SourcePhone *commsEmailLogRSourcePhoneR
DestinationEmailContact *commsEmailLogRDestinationEmailContactR
TemplateEmailTemplate *commsEmailLogRTemplateEmailTemplateR
}
type commsEmailLogRDestinationEmailR struct {
o *CommsEmailTemplate
type commsEmailLogRDestinationEmailContactR struct {
o *CommsEmailContactTemplate
}
type commsEmailLogRSourcePhoneR struct {
o *CommsPhoneTemplate
type commsEmailLogRTemplateEmailTemplateR struct {
o *CommsEmailTemplateTemplate
}
// Apply mods to the CommsEmailLogTemplate
@ -69,18 +79,18 @@ func (o *CommsEmailLogTemplate) Apply(ctx context.Context, mods ...CommsEmailLog
// setModelRels creates and sets the relationships on *models.CommsEmailLog
// according to the relationships in the template. Nothing is inserted into the db
func (t CommsEmailLogTemplate) setModelRels(o *models.CommsEmailLog) {
if t.r.DestinationEmail != nil {
rel := t.r.DestinationEmail.o.Build()
if t.r.DestinationEmailContact != nil {
rel := t.r.DestinationEmailContact.o.Build()
rel.R.DestinationEmailLogs = append(rel.R.DestinationEmailLogs, o)
o.Destination = rel.Address // h2
o.R.DestinationEmail = rel
o.R.DestinationEmailContact = rel
}
if t.r.SourcePhone != nil {
rel := t.r.SourcePhone.o.Build()
rel.R.SourceEmailLogs = append(rel.R.SourceEmailLogs, o)
o.Source = rel.E164 // h2
o.R.SourcePhone = rel
if t.r.TemplateEmailTemplate != nil {
rel := t.r.TemplateEmailTemplate.o.Build()
rel.R.TemplateEmailLogs = append(rel.R.TemplateEmailLogs, o)
o.TemplateID = null.From(rel.ID) // h2
o.R.TemplateEmailTemplate = rel
}
}
@ -89,18 +99,46 @@ func (t CommsEmailLogTemplate) setModelRels(o *models.CommsEmailLog) {
func (o CommsEmailLogTemplate) BuildSetter() *models.CommsEmailLogSetter {
m := &models.CommsEmailLogSetter{}
if o.ID != nil {
val := o.ID()
m.ID = omit.From(val)
}
if o.Created != nil {
val := o.Created()
m.Created = omit.From(val)
}
if o.DeliveryStatus != nil {
val := o.DeliveryStatus()
m.DeliveryStatus = omit.From(val)
}
if o.Destination != nil {
val := o.Destination()
m.Destination = omit.From(val)
}
if o.PublicID != nil {
val := o.PublicID()
m.PublicID = omit.From(val)
}
if o.SentAt != nil {
val := o.SentAt()
m.SentAt = omitnull.FromNull(val)
}
if o.Source != nil {
val := o.Source()
m.Source = omit.From(val)
}
if o.Subject != nil {
val := o.Subject()
m.Subject = omit.From(val)
}
if o.TemplateID != nil {
val := o.TemplateID()
m.TemplateID = omitnull.FromNull(val)
}
if o.TemplateData != nil {
val := o.TemplateData()
m.TemplateData = omit.From(val)
}
if o.Type != nil {
val := o.Type()
m.Type = omit.From(val)
@ -127,15 +165,36 @@ func (o CommsEmailLogTemplate) BuildManySetter(number int) []*models.CommsEmailL
func (o CommsEmailLogTemplate) Build() *models.CommsEmailLog {
m := &models.CommsEmailLog{}
if o.ID != nil {
m.ID = o.ID()
}
if o.Created != nil {
m.Created = o.Created()
}
if o.DeliveryStatus != nil {
m.DeliveryStatus = o.DeliveryStatus()
}
if o.Destination != nil {
m.Destination = o.Destination()
}
if o.PublicID != nil {
m.PublicID = o.PublicID()
}
if o.SentAt != nil {
m.SentAt = o.SentAt()
}
if o.Source != nil {
m.Source = o.Source()
}
if o.Subject != nil {
m.Subject = o.Subject()
}
if o.TemplateID != nil {
m.TemplateID = o.TemplateID()
}
if o.TemplateData != nil {
m.TemplateData = o.TemplateData()
}
if o.Type != nil {
m.Type = o.Type()
}
@ -163,14 +222,30 @@ func ensureCreatableCommsEmailLog(m *models.CommsEmailLogSetter) {
val := random_time_Time(nil)
m.Created = omit.From(val)
}
if !(m.DeliveryStatus.IsValue()) {
val := random_string(nil, "16")
m.DeliveryStatus = omit.From(val)
}
if !(m.Destination.IsValue()) {
val := random_string(nil)
m.Destination = omit.From(val)
}
if !(m.PublicID.IsValue()) {
val := random_string(nil, "64")
m.PublicID = omit.From(val)
}
if !(m.Source.IsValue()) {
val := random_string(nil)
m.Source = omit.From(val)
}
if !(m.Subject.IsValue()) {
val := random_string(nil, "255")
m.Subject = omit.From(val)
}
if !(m.TemplateData.IsValue()) {
val := random_pgtypes_HStore(nil)
m.TemplateData = omit.From(val)
}
if !(m.Type.IsValue()) {
val := random_enums_CommsMessagetypeemail(nil)
m.Type = omit.From(val)
@ -183,6 +258,25 @@ func ensureCreatableCommsEmailLog(m *models.CommsEmailLogSetter) {
func (o *CommsEmailLogTemplate) insertOptRels(ctx context.Context, exec bob.Executor, m *models.CommsEmailLog) error {
var err error
isTemplateEmailTemplateDone, _ := commsEmailLogRelTemplateEmailTemplateCtx.Value(ctx)
if !isTemplateEmailTemplateDone && o.r.TemplateEmailTemplate != nil {
ctx = commsEmailLogRelTemplateEmailTemplateCtx.WithValue(ctx, true)
if o.r.TemplateEmailTemplate.o.alreadyPersisted {
m.R.TemplateEmailTemplate = o.r.TemplateEmailTemplate.o.Build()
} else {
var rel1 *models.CommsEmailTemplate
rel1, err = o.r.TemplateEmailTemplate.o.Create(ctx, exec)
if err != nil {
return err
}
err = m.AttachTemplateEmailTemplate(ctx, exec, rel1)
if err != nil {
return err
}
}
}
return err
}
@ -193,16 +287,16 @@ func (o *CommsEmailLogTemplate) Create(ctx context.Context, exec bob.Executor) (
opt := o.BuildSetter()
ensureCreatableCommsEmailLog(opt)
if o.r.DestinationEmail == nil {
CommsEmailLogMods.WithNewDestinationEmail().Apply(ctx, o)
if o.r.DestinationEmailContact == nil {
CommsEmailLogMods.WithNewDestinationEmailContact().Apply(ctx, o)
}
var rel0 *models.CommsEmail
var rel0 *models.CommsEmailContact
if o.r.DestinationEmail.o.alreadyPersisted {
rel0 = o.r.DestinationEmail.o.Build()
if o.r.DestinationEmailContact.o.alreadyPersisted {
rel0 = o.r.DestinationEmailContact.o.Build()
} else {
rel0, err = o.r.DestinationEmail.o.Create(ctx, exec)
rel0, err = o.r.DestinationEmailContact.o.Create(ctx, exec)
if err != nil {
return nil, err
}
@ -210,30 +304,12 @@ func (o *CommsEmailLogTemplate) Create(ctx context.Context, exec bob.Executor) (
opt.Destination = omit.From(rel0.Address)
if o.r.SourcePhone == nil {
CommsEmailLogMods.WithNewSourcePhone().Apply(ctx, o)
}
var rel1 *models.CommsPhone
if o.r.SourcePhone.o.alreadyPersisted {
rel1 = o.r.SourcePhone.o.Build()
} else {
rel1, err = o.r.SourcePhone.o.Create(ctx, exec)
if err != nil {
return nil, err
}
}
opt.Source = omit.From(rel1.E164)
m, err := models.CommsEmailLogs.Insert(opt).One(ctx, exec)
if err != nil {
return nil, err
}
m.R.DestinationEmail = rel0
m.R.SourcePhone = rel1
m.R.DestinationEmailContact = rel0
if err := o.insertOptRels(ctx, exec, m); err != nil {
return nil, err
@ -312,13 +388,51 @@ type commsEmailLogMods struct{}
func (m commsEmailLogMods) RandomizeAllColumns(f *faker.Faker) CommsEmailLogMod {
return CommsEmailLogModSlice{
CommsEmailLogMods.RandomID(f),
CommsEmailLogMods.RandomCreated(f),
CommsEmailLogMods.RandomDeliveryStatus(f),
CommsEmailLogMods.RandomDestination(f),
CommsEmailLogMods.RandomPublicID(f),
CommsEmailLogMods.RandomSentAt(f),
CommsEmailLogMods.RandomSource(f),
CommsEmailLogMods.RandomSubject(f),
CommsEmailLogMods.RandomTemplateID(f),
CommsEmailLogMods.RandomTemplateData(f),
CommsEmailLogMods.RandomType(f),
}
}
// Set the model columns to this value
func (m commsEmailLogMods) ID(val int32) CommsEmailLogMod {
return CommsEmailLogModFunc(func(_ context.Context, o *CommsEmailLogTemplate) {
o.ID = func() int32 { return val }
})
}
// Set the Column from the function
func (m commsEmailLogMods) IDFunc(f func() int32) CommsEmailLogMod {
return CommsEmailLogModFunc(func(_ context.Context, o *CommsEmailLogTemplate) {
o.ID = f
})
}
// Clear any values for the column
func (m commsEmailLogMods) UnsetID() CommsEmailLogMod {
return CommsEmailLogModFunc(func(_ context.Context, o *CommsEmailLogTemplate) {
o.ID = nil
})
}
// Generates a random value for the column using the given faker
// if faker is nil, a default faker is used
func (m commsEmailLogMods) RandomID(f *faker.Faker) CommsEmailLogMod {
return CommsEmailLogModFunc(func(_ context.Context, o *CommsEmailLogTemplate) {
o.ID = func() int32 {
return random_int32(f)
}
})
}
// Set the model columns to this value
func (m commsEmailLogMods) Created(val time.Time) CommsEmailLogMod {
return CommsEmailLogModFunc(func(_ context.Context, o *CommsEmailLogTemplate) {
@ -350,6 +464,37 @@ func (m commsEmailLogMods) RandomCreated(f *faker.Faker) CommsEmailLogMod {
})
}
// Set the model columns to this value
func (m commsEmailLogMods) DeliveryStatus(val string) CommsEmailLogMod {
return CommsEmailLogModFunc(func(_ context.Context, o *CommsEmailLogTemplate) {
o.DeliveryStatus = func() string { return val }
})
}
// Set the Column from the function
func (m commsEmailLogMods) DeliveryStatusFunc(f func() string) CommsEmailLogMod {
return CommsEmailLogModFunc(func(_ context.Context, o *CommsEmailLogTemplate) {
o.DeliveryStatus = f
})
}
// Clear any values for the column
func (m commsEmailLogMods) UnsetDeliveryStatus() CommsEmailLogMod {
return CommsEmailLogModFunc(func(_ context.Context, o *CommsEmailLogTemplate) {
o.DeliveryStatus = nil
})
}
// Generates a random value for the column using the given faker
// if faker is nil, a default faker is used
func (m commsEmailLogMods) RandomDeliveryStatus(f *faker.Faker) CommsEmailLogMod {
return CommsEmailLogModFunc(func(_ context.Context, o *CommsEmailLogTemplate) {
o.DeliveryStatus = func() string {
return random_string(f, "16")
}
})
}
// Set the model columns to this value
func (m commsEmailLogMods) Destination(val string) CommsEmailLogMod {
return CommsEmailLogModFunc(func(_ context.Context, o *CommsEmailLogTemplate) {
@ -381,6 +526,90 @@ func (m commsEmailLogMods) RandomDestination(f *faker.Faker) CommsEmailLogMod {
})
}
// Set the model columns to this value
func (m commsEmailLogMods) PublicID(val string) CommsEmailLogMod {
return CommsEmailLogModFunc(func(_ context.Context, o *CommsEmailLogTemplate) {
o.PublicID = func() string { return val }
})
}
// Set the Column from the function
func (m commsEmailLogMods) PublicIDFunc(f func() string) CommsEmailLogMod {
return CommsEmailLogModFunc(func(_ context.Context, o *CommsEmailLogTemplate) {
o.PublicID = f
})
}
// Clear any values for the column
func (m commsEmailLogMods) UnsetPublicID() CommsEmailLogMod {
return CommsEmailLogModFunc(func(_ context.Context, o *CommsEmailLogTemplate) {
o.PublicID = nil
})
}
// Generates a random value for the column using the given faker
// if faker is nil, a default faker is used
func (m commsEmailLogMods) RandomPublicID(f *faker.Faker) CommsEmailLogMod {
return CommsEmailLogModFunc(func(_ context.Context, o *CommsEmailLogTemplate) {
o.PublicID = func() string {
return random_string(f, "64")
}
})
}
// Set the model columns to this value
func (m commsEmailLogMods) SentAt(val null.Val[time.Time]) CommsEmailLogMod {
return CommsEmailLogModFunc(func(_ context.Context, o *CommsEmailLogTemplate) {
o.SentAt = func() null.Val[time.Time] { return val }
})
}
// Set the Column from the function
func (m commsEmailLogMods) SentAtFunc(f func() null.Val[time.Time]) CommsEmailLogMod {
return CommsEmailLogModFunc(func(_ context.Context, o *CommsEmailLogTemplate) {
o.SentAt = f
})
}
// Clear any values for the column
func (m commsEmailLogMods) UnsetSentAt() CommsEmailLogMod {
return CommsEmailLogModFunc(func(_ context.Context, o *CommsEmailLogTemplate) {
o.SentAt = nil
})
}
// Generates a random value for the column using the given faker
// if faker is nil, a default faker is used
// The generated value is sometimes null
func (m commsEmailLogMods) RandomSentAt(f *faker.Faker) CommsEmailLogMod {
return CommsEmailLogModFunc(func(_ context.Context, o *CommsEmailLogTemplate) {
o.SentAt = func() null.Val[time.Time] {
if f == nil {
f = &defaultFaker
}
val := random_time_Time(f)
return null.From(val)
}
})
}
// Generates a random value for the column using the given faker
// if faker is nil, a default faker is used
// The generated value is never null
func (m commsEmailLogMods) RandomSentAtNotNull(f *faker.Faker) CommsEmailLogMod {
return CommsEmailLogModFunc(func(_ context.Context, o *CommsEmailLogTemplate) {
o.SentAt = func() null.Val[time.Time] {
if f == nil {
f = &defaultFaker
}
val := random_time_Time(f)
return null.From(val)
}
})
}
// Set the model columns to this value
func (m commsEmailLogMods) Source(val string) CommsEmailLogMod {
return CommsEmailLogModFunc(func(_ context.Context, o *CommsEmailLogTemplate) {
@ -412,6 +641,121 @@ func (m commsEmailLogMods) RandomSource(f *faker.Faker) CommsEmailLogMod {
})
}
// Set the model columns to this value
func (m commsEmailLogMods) Subject(val string) CommsEmailLogMod {
return CommsEmailLogModFunc(func(_ context.Context, o *CommsEmailLogTemplate) {
o.Subject = func() string { return val }
})
}
// Set the Column from the function
func (m commsEmailLogMods) SubjectFunc(f func() string) CommsEmailLogMod {
return CommsEmailLogModFunc(func(_ context.Context, o *CommsEmailLogTemplate) {
o.Subject = f
})
}
// Clear any values for the column
func (m commsEmailLogMods) UnsetSubject() CommsEmailLogMod {
return CommsEmailLogModFunc(func(_ context.Context, o *CommsEmailLogTemplate) {
o.Subject = nil
})
}
// Generates a random value for the column using the given faker
// if faker is nil, a default faker is used
func (m commsEmailLogMods) RandomSubject(f *faker.Faker) CommsEmailLogMod {
return CommsEmailLogModFunc(func(_ context.Context, o *CommsEmailLogTemplate) {
o.Subject = func() string {
return random_string(f, "255")
}
})
}
// Set the model columns to this value
func (m commsEmailLogMods) TemplateID(val null.Val[int32]) CommsEmailLogMod {
return CommsEmailLogModFunc(func(_ context.Context, o *CommsEmailLogTemplate) {
o.TemplateID = func() null.Val[int32] { return val }
})
}
// Set the Column from the function
func (m commsEmailLogMods) TemplateIDFunc(f func() null.Val[int32]) CommsEmailLogMod {
return CommsEmailLogModFunc(func(_ context.Context, o *CommsEmailLogTemplate) {
o.TemplateID = f
})
}
// Clear any values for the column
func (m commsEmailLogMods) UnsetTemplateID() CommsEmailLogMod {
return CommsEmailLogModFunc(func(_ context.Context, o *CommsEmailLogTemplate) {
o.TemplateID = nil
})
}
// Generates a random value for the column using the given faker
// if faker is nil, a default faker is used
// The generated value is sometimes null
func (m commsEmailLogMods) RandomTemplateID(f *faker.Faker) CommsEmailLogMod {
return CommsEmailLogModFunc(func(_ context.Context, o *CommsEmailLogTemplate) {
o.TemplateID = func() null.Val[int32] {
if f == nil {
f = &defaultFaker
}
val := random_int32(f)
return null.From(val)
}
})
}
// Generates a random value for the column using the given faker
// if faker is nil, a default faker is used
// The generated value is never null
func (m commsEmailLogMods) RandomTemplateIDNotNull(f *faker.Faker) CommsEmailLogMod {
return CommsEmailLogModFunc(func(_ context.Context, o *CommsEmailLogTemplate) {
o.TemplateID = func() null.Val[int32] {
if f == nil {
f = &defaultFaker
}
val := random_int32(f)
return null.From(val)
}
})
}
// Set the model columns to this value
func (m commsEmailLogMods) TemplateData(val pgtypes.HStore) CommsEmailLogMod {
return CommsEmailLogModFunc(func(_ context.Context, o *CommsEmailLogTemplate) {
o.TemplateData = func() pgtypes.HStore { return val }
})
}
// Set the Column from the function
func (m commsEmailLogMods) TemplateDataFunc(f func() pgtypes.HStore) CommsEmailLogMod {
return CommsEmailLogModFunc(func(_ context.Context, o *CommsEmailLogTemplate) {
o.TemplateData = f
})
}
// Clear any values for the column
func (m commsEmailLogMods) UnsetTemplateData() CommsEmailLogMod {
return CommsEmailLogModFunc(func(_ context.Context, o *CommsEmailLogTemplate) {
o.TemplateData = nil
})
}
// Generates a random value for the column using the given faker
// if faker is nil, a default faker is used
func (m commsEmailLogMods) RandomTemplateData(f *faker.Faker) CommsEmailLogMod {
return CommsEmailLogModFunc(func(_ context.Context, o *CommsEmailLogTemplate) {
o.TemplateData = func() pgtypes.HStore {
return random_pgtypes_HStore(f)
}
})
}
// Set the model columns to this value
func (m commsEmailLogMods) Type(val enums.CommsMessagetypeemail) CommsEmailLogMod {
return CommsEmailLogModFunc(func(_ context.Context, o *CommsEmailLogTemplate) {
@ -451,73 +795,73 @@ func (m commsEmailLogMods) WithParentsCascading() CommsEmailLogMod {
ctx = commsEmailLogWithParentsCascadingCtx.WithValue(ctx, true)
{
related := o.f.NewCommsEmailWithContext(ctx, CommsEmailMods.WithParentsCascading())
m.WithDestinationEmail(related).Apply(ctx, o)
related := o.f.NewCommsEmailContactWithContext(ctx, CommsEmailContactMods.WithParentsCascading())
m.WithDestinationEmailContact(related).Apply(ctx, o)
}
{
related := o.f.NewCommsPhoneWithContext(ctx, CommsPhoneMods.WithParentsCascading())
m.WithSourcePhone(related).Apply(ctx, o)
related := o.f.NewCommsEmailTemplateWithContext(ctx, CommsEmailTemplateMods.WithParentsCascading())
m.WithTemplateEmailTemplate(related).Apply(ctx, o)
}
})
}
func (m commsEmailLogMods) WithDestinationEmail(rel *CommsEmailTemplate) CommsEmailLogMod {
func (m commsEmailLogMods) WithDestinationEmailContact(rel *CommsEmailContactTemplate) CommsEmailLogMod {
return CommsEmailLogModFunc(func(ctx context.Context, o *CommsEmailLogTemplate) {
o.r.DestinationEmail = &commsEmailLogRDestinationEmailR{
o.r.DestinationEmailContact = &commsEmailLogRDestinationEmailContactR{
o: rel,
}
})
}
func (m commsEmailLogMods) WithNewDestinationEmail(mods ...CommsEmailMod) CommsEmailLogMod {
func (m commsEmailLogMods) WithNewDestinationEmailContact(mods ...CommsEmailContactMod) CommsEmailLogMod {
return CommsEmailLogModFunc(func(ctx context.Context, o *CommsEmailLogTemplate) {
related := o.f.NewCommsEmailWithContext(ctx, mods...)
related := o.f.NewCommsEmailContactWithContext(ctx, mods...)
m.WithDestinationEmail(related).Apply(ctx, o)
m.WithDestinationEmailContact(related).Apply(ctx, o)
})
}
func (m commsEmailLogMods) WithExistingDestinationEmail(em *models.CommsEmail) CommsEmailLogMod {
func (m commsEmailLogMods) WithExistingDestinationEmailContact(em *models.CommsEmailContact) CommsEmailLogMod {
return CommsEmailLogModFunc(func(ctx context.Context, o *CommsEmailLogTemplate) {
o.r.DestinationEmail = &commsEmailLogRDestinationEmailR{
o: o.f.FromExistingCommsEmail(em),
o.r.DestinationEmailContact = &commsEmailLogRDestinationEmailContactR{
o: o.f.FromExistingCommsEmailContact(em),
}
})
}
func (m commsEmailLogMods) WithoutDestinationEmail() CommsEmailLogMod {
func (m commsEmailLogMods) WithoutDestinationEmailContact() CommsEmailLogMod {
return CommsEmailLogModFunc(func(ctx context.Context, o *CommsEmailLogTemplate) {
o.r.DestinationEmail = nil
o.r.DestinationEmailContact = nil
})
}
func (m commsEmailLogMods) WithSourcePhone(rel *CommsPhoneTemplate) CommsEmailLogMod {
func (m commsEmailLogMods) WithTemplateEmailTemplate(rel *CommsEmailTemplateTemplate) CommsEmailLogMod {
return CommsEmailLogModFunc(func(ctx context.Context, o *CommsEmailLogTemplate) {
o.r.SourcePhone = &commsEmailLogRSourcePhoneR{
o.r.TemplateEmailTemplate = &commsEmailLogRTemplateEmailTemplateR{
o: rel,
}
})
}
func (m commsEmailLogMods) WithNewSourcePhone(mods ...CommsPhoneMod) CommsEmailLogMod {
func (m commsEmailLogMods) WithNewTemplateEmailTemplate(mods ...CommsEmailTemplateMod) CommsEmailLogMod {
return CommsEmailLogModFunc(func(ctx context.Context, o *CommsEmailLogTemplate) {
related := o.f.NewCommsPhoneWithContext(ctx, mods...)
related := o.f.NewCommsEmailTemplateWithContext(ctx, mods...)
m.WithSourcePhone(related).Apply(ctx, o)
m.WithTemplateEmailTemplate(related).Apply(ctx, o)
})
}
func (m commsEmailLogMods) WithExistingSourcePhone(em *models.CommsPhone) CommsEmailLogMod {
func (m commsEmailLogMods) WithExistingTemplateEmailTemplate(em *models.CommsEmailTemplate) CommsEmailLogMod {
return CommsEmailLogModFunc(func(ctx context.Context, o *CommsEmailLogTemplate) {
o.r.SourcePhone = &commsEmailLogRSourcePhoneR{
o: o.f.FromExistingCommsPhone(em),
o.r.TemplateEmailTemplate = &commsEmailLogRTemplateEmailTemplateR{
o: o.f.FromExistingCommsEmailTemplate(em),
}
})
}
func (m commsEmailLogMods) WithoutSourcePhone() CommsEmailLogMod {
func (m commsEmailLogMods) WithoutTemplateEmailTemplate() CommsEmailLogMod {
return CommsEmailLogModFunc(func(ctx context.Context, o *CommsEmailLogTemplate) {
o.r.SourcePhone = nil
o.r.TemplateEmailTemplate = nil
})
}

View file

@ -0,0 +1,672 @@
// Code generated by BobGen psql v0.42.1. DO NOT EDIT.
// This file is meant to be re-generated in place and/or deleted at any time.
package factory
import (
"context"
"testing"
"time"
enums "github.com/Gleipnir-Technology/nidus-sync/db/enums"
models "github.com/Gleipnir-Technology/nidus-sync/db/models"
"github.com/aarondl/opt/null"
"github.com/aarondl/opt/omit"
"github.com/aarondl/opt/omitnull"
"github.com/jaswdr/faker/v2"
"github.com/stephenafamo/bob"
)
type CommsEmailTemplateMod interface {
Apply(context.Context, *CommsEmailTemplateTemplate)
}
type CommsEmailTemplateModFunc func(context.Context, *CommsEmailTemplateTemplate)
func (f CommsEmailTemplateModFunc) Apply(ctx context.Context, n *CommsEmailTemplateTemplate) {
f(ctx, n)
}
type CommsEmailTemplateModSlice []CommsEmailTemplateMod
func (mods CommsEmailTemplateModSlice) Apply(ctx context.Context, n *CommsEmailTemplateTemplate) {
for _, f := range mods {
f.Apply(ctx, n)
}
}
// CommsEmailTemplateTemplate is an object representing the database table.
// all columns are optional and should be set by mods
type CommsEmailTemplateTemplate struct {
ContentHTML func() string
ContentTXT func() string
ContentHashHTML func() string
ContentHashTXT func() string
Created func() time.Time
ID func() int32
Superceded func() null.Val[time.Time]
MessageType func() enums.CommsMessagetypeemail
r commsEmailTemplateR
f *Factory
alreadyPersisted bool
}
type commsEmailTemplateR struct {
TemplateEmailLogs []*commsEmailTemplateRTemplateEmailLogsR
}
type commsEmailTemplateRTemplateEmailLogsR struct {
number int
o *CommsEmailLogTemplate
}
// Apply mods to the CommsEmailTemplateTemplate
func (o *CommsEmailTemplateTemplate) Apply(ctx context.Context, mods ...CommsEmailTemplateMod) {
for _, mod := range mods {
mod.Apply(ctx, o)
}
}
// setModelRels creates and sets the relationships on *models.CommsEmailTemplate
// according to the relationships in the template. Nothing is inserted into the db
func (t CommsEmailTemplateTemplate) setModelRels(o *models.CommsEmailTemplate) {
if t.r.TemplateEmailLogs != nil {
rel := models.CommsEmailLogSlice{}
for _, r := range t.r.TemplateEmailLogs {
related := r.o.BuildMany(r.number)
for _, rel := range related {
rel.TemplateID = null.From(o.ID) // h2
rel.R.TemplateEmailTemplate = o
}
rel = append(rel, related...)
}
o.R.TemplateEmailLogs = rel
}
}
// BuildSetter returns an *models.CommsEmailTemplateSetter
// this does nothing with the relationship templates
func (o CommsEmailTemplateTemplate) BuildSetter() *models.CommsEmailTemplateSetter {
m := &models.CommsEmailTemplateSetter{}
if o.ContentHTML != nil {
val := o.ContentHTML()
m.ContentHTML = omit.From(val)
}
if o.ContentTXT != nil {
val := o.ContentTXT()
m.ContentTXT = omit.From(val)
}
if o.ContentHashHTML != nil {
val := o.ContentHashHTML()
m.ContentHashHTML = omit.From(val)
}
if o.ContentHashTXT != nil {
val := o.ContentHashTXT()
m.ContentHashTXT = omit.From(val)
}
if o.Created != nil {
val := o.Created()
m.Created = omit.From(val)
}
if o.ID != nil {
val := o.ID()
m.ID = omit.From(val)
}
if o.Superceded != nil {
val := o.Superceded()
m.Superceded = omitnull.FromNull(val)
}
if o.MessageType != nil {
val := o.MessageType()
m.MessageType = omit.From(val)
}
return m
}
// BuildManySetter returns an []*models.CommsEmailTemplateSetter
// this does nothing with the relationship templates
func (o CommsEmailTemplateTemplate) BuildManySetter(number int) []*models.CommsEmailTemplateSetter {
m := make([]*models.CommsEmailTemplateSetter, number)
for i := range m {
m[i] = o.BuildSetter()
}
return m
}
// Build returns an *models.CommsEmailTemplate
// Related objects are also created and placed in the .R field
// NOTE: Objects are not inserted into the database. Use CommsEmailTemplateTemplate.Create
func (o CommsEmailTemplateTemplate) Build() *models.CommsEmailTemplate {
m := &models.CommsEmailTemplate{}
if o.ContentHTML != nil {
m.ContentHTML = o.ContentHTML()
}
if o.ContentTXT != nil {
m.ContentTXT = o.ContentTXT()
}
if o.ContentHashHTML != nil {
m.ContentHashHTML = o.ContentHashHTML()
}
if o.ContentHashTXT != nil {
m.ContentHashTXT = o.ContentHashTXT()
}
if o.Created != nil {
m.Created = o.Created()
}
if o.ID != nil {
m.ID = o.ID()
}
if o.Superceded != nil {
m.Superceded = o.Superceded()
}
if o.MessageType != nil {
m.MessageType = o.MessageType()
}
o.setModelRels(m)
return m
}
// BuildMany returns an models.CommsEmailTemplateSlice
// Related objects are also created and placed in the .R field
// NOTE: Objects are not inserted into the database. Use CommsEmailTemplateTemplate.CreateMany
func (o CommsEmailTemplateTemplate) BuildMany(number int) models.CommsEmailTemplateSlice {
m := make(models.CommsEmailTemplateSlice, number)
for i := range m {
m[i] = o.Build()
}
return m
}
func ensureCreatableCommsEmailTemplate(m *models.CommsEmailTemplateSetter) {
if !(m.ContentHTML.IsValue()) {
val := random_string(nil)
m.ContentHTML = omit.From(val)
}
if !(m.ContentTXT.IsValue()) {
val := random_string(nil)
m.ContentTXT = omit.From(val)
}
if !(m.ContentHashHTML.IsValue()) {
val := random_string(nil, "64")
m.ContentHashHTML = omit.From(val)
}
if !(m.ContentHashTXT.IsValue()) {
val := random_string(nil, "64")
m.ContentHashTXT = omit.From(val)
}
if !(m.Created.IsValue()) {
val := random_time_Time(nil)
m.Created = omit.From(val)
}
if !(m.MessageType.IsValue()) {
val := random_enums_CommsMessagetypeemail(nil)
m.MessageType = omit.From(val)
}
}
// insertOptRels creates and inserts any optional the relationships on *models.CommsEmailTemplate
// according to the relationships in the template.
// any required relationship should have already exist on the model
func (o *CommsEmailTemplateTemplate) insertOptRels(ctx context.Context, exec bob.Executor, m *models.CommsEmailTemplate) error {
var err error
isTemplateEmailLogsDone, _ := commsEmailTemplateRelTemplateEmailLogsCtx.Value(ctx)
if !isTemplateEmailLogsDone && o.r.TemplateEmailLogs != nil {
ctx = commsEmailTemplateRelTemplateEmailLogsCtx.WithValue(ctx, true)
for _, r := range o.r.TemplateEmailLogs {
if r.o.alreadyPersisted {
m.R.TemplateEmailLogs = append(m.R.TemplateEmailLogs, r.o.Build())
} else {
rel0, err := r.o.CreateMany(ctx, exec, r.number)
if err != nil {
return err
}
err = m.AttachTemplateEmailLogs(ctx, exec, rel0...)
if err != nil {
return err
}
}
}
}
return err
}
// Create builds a commsEmailTemplate and inserts it into the database
// Relations objects are also inserted and placed in the .R field
func (o *CommsEmailTemplateTemplate) Create(ctx context.Context, exec bob.Executor) (*models.CommsEmailTemplate, error) {
var err error
opt := o.BuildSetter()
ensureCreatableCommsEmailTemplate(opt)
m, err := models.CommsEmailTemplates.Insert(opt).One(ctx, exec)
if err != nil {
return nil, err
}
if err := o.insertOptRels(ctx, exec, m); err != nil {
return nil, err
}
return m, err
}
// MustCreate builds a commsEmailTemplate and inserts it into the database
// Relations objects are also inserted and placed in the .R field
// panics if an error occurs
func (o *CommsEmailTemplateTemplate) MustCreate(ctx context.Context, exec bob.Executor) *models.CommsEmailTemplate {
m, err := o.Create(ctx, exec)
if err != nil {
panic(err)
}
return m
}
// CreateOrFail builds a commsEmailTemplate and inserts it into the database
// Relations objects are also inserted and placed in the .R field
// It calls `tb.Fatal(err)` on the test/benchmark if an error occurs
func (o *CommsEmailTemplateTemplate) CreateOrFail(ctx context.Context, tb testing.TB, exec bob.Executor) *models.CommsEmailTemplate {
tb.Helper()
m, err := o.Create(ctx, exec)
if err != nil {
tb.Fatal(err)
return nil
}
return m
}
// CreateMany builds multiple commsEmailTemplates and inserts them into the database
// Relations objects are also inserted and placed in the .R field
func (o CommsEmailTemplateTemplate) CreateMany(ctx context.Context, exec bob.Executor, number int) (models.CommsEmailTemplateSlice, error) {
var err error
m := make(models.CommsEmailTemplateSlice, number)
for i := range m {
m[i], err = o.Create(ctx, exec)
if err != nil {
return nil, err
}
}
return m, nil
}
// MustCreateMany builds multiple commsEmailTemplates and inserts them into the database
// Relations objects are also inserted and placed in the .R field
// panics if an error occurs
func (o CommsEmailTemplateTemplate) MustCreateMany(ctx context.Context, exec bob.Executor, number int) models.CommsEmailTemplateSlice {
m, err := o.CreateMany(ctx, exec, number)
if err != nil {
panic(err)
}
return m
}
// CreateManyOrFail builds multiple commsEmailTemplates and inserts them into the database
// Relations objects are also inserted and placed in the .R field
// It calls `tb.Fatal(err)` on the test/benchmark if an error occurs
func (o CommsEmailTemplateTemplate) CreateManyOrFail(ctx context.Context, tb testing.TB, exec bob.Executor, number int) models.CommsEmailTemplateSlice {
tb.Helper()
m, err := o.CreateMany(ctx, exec, number)
if err != nil {
tb.Fatal(err)
return nil
}
return m
}
// CommsEmailTemplate has methods that act as mods for the CommsEmailTemplateTemplate
var CommsEmailTemplateMods commsEmailTemplateMods
type commsEmailTemplateMods struct{}
func (m commsEmailTemplateMods) RandomizeAllColumns(f *faker.Faker) CommsEmailTemplateMod {
return CommsEmailTemplateModSlice{
CommsEmailTemplateMods.RandomContentHTML(f),
CommsEmailTemplateMods.RandomContentTXT(f),
CommsEmailTemplateMods.RandomContentHashHTML(f),
CommsEmailTemplateMods.RandomContentHashTXT(f),
CommsEmailTemplateMods.RandomCreated(f),
CommsEmailTemplateMods.RandomID(f),
CommsEmailTemplateMods.RandomSuperceded(f),
CommsEmailTemplateMods.RandomMessageType(f),
}
}
// Set the model columns to this value
func (m commsEmailTemplateMods) ContentHTML(val string) CommsEmailTemplateMod {
return CommsEmailTemplateModFunc(func(_ context.Context, o *CommsEmailTemplateTemplate) {
o.ContentHTML = func() string { return val }
})
}
// Set the Column from the function
func (m commsEmailTemplateMods) ContentHTMLFunc(f func() string) CommsEmailTemplateMod {
return CommsEmailTemplateModFunc(func(_ context.Context, o *CommsEmailTemplateTemplate) {
o.ContentHTML = f
})
}
// Clear any values for the column
func (m commsEmailTemplateMods) UnsetContentHTML() CommsEmailTemplateMod {
return CommsEmailTemplateModFunc(func(_ context.Context, o *CommsEmailTemplateTemplate) {
o.ContentHTML = nil
})
}
// Generates a random value for the column using the given faker
// if faker is nil, a default faker is used
func (m commsEmailTemplateMods) RandomContentHTML(f *faker.Faker) CommsEmailTemplateMod {
return CommsEmailTemplateModFunc(func(_ context.Context, o *CommsEmailTemplateTemplate) {
o.ContentHTML = func() string {
return random_string(f)
}
})
}
// Set the model columns to this value
func (m commsEmailTemplateMods) ContentTXT(val string) CommsEmailTemplateMod {
return CommsEmailTemplateModFunc(func(_ context.Context, o *CommsEmailTemplateTemplate) {
o.ContentTXT = func() string { return val }
})
}
// Set the Column from the function
func (m commsEmailTemplateMods) ContentTXTFunc(f func() string) CommsEmailTemplateMod {
return CommsEmailTemplateModFunc(func(_ context.Context, o *CommsEmailTemplateTemplate) {
o.ContentTXT = f
})
}
// Clear any values for the column
func (m commsEmailTemplateMods) UnsetContentTXT() CommsEmailTemplateMod {
return CommsEmailTemplateModFunc(func(_ context.Context, o *CommsEmailTemplateTemplate) {
o.ContentTXT = nil
})
}
// Generates a random value for the column using the given faker
// if faker is nil, a default faker is used
func (m commsEmailTemplateMods) RandomContentTXT(f *faker.Faker) CommsEmailTemplateMod {
return CommsEmailTemplateModFunc(func(_ context.Context, o *CommsEmailTemplateTemplate) {
o.ContentTXT = func() string {
return random_string(f)
}
})
}
// Set the model columns to this value
func (m commsEmailTemplateMods) ContentHashHTML(val string) CommsEmailTemplateMod {
return CommsEmailTemplateModFunc(func(_ context.Context, o *CommsEmailTemplateTemplate) {
o.ContentHashHTML = func() string { return val }
})
}
// Set the Column from the function
func (m commsEmailTemplateMods) ContentHashHTMLFunc(f func() string) CommsEmailTemplateMod {
return CommsEmailTemplateModFunc(func(_ context.Context, o *CommsEmailTemplateTemplate) {
o.ContentHashHTML = f
})
}
// Clear any values for the column
func (m commsEmailTemplateMods) UnsetContentHashHTML() CommsEmailTemplateMod {
return CommsEmailTemplateModFunc(func(_ context.Context, o *CommsEmailTemplateTemplate) {
o.ContentHashHTML = nil
})
}
// Generates a random value for the column using the given faker
// if faker is nil, a default faker is used
func (m commsEmailTemplateMods) RandomContentHashHTML(f *faker.Faker) CommsEmailTemplateMod {
return CommsEmailTemplateModFunc(func(_ context.Context, o *CommsEmailTemplateTemplate) {
o.ContentHashHTML = func() string {
return random_string(f, "64")
}
})
}
// Set the model columns to this value
func (m commsEmailTemplateMods) ContentHashTXT(val string) CommsEmailTemplateMod {
return CommsEmailTemplateModFunc(func(_ context.Context, o *CommsEmailTemplateTemplate) {
o.ContentHashTXT = func() string { return val }
})
}
// Set the Column from the function
func (m commsEmailTemplateMods) ContentHashTXTFunc(f func() string) CommsEmailTemplateMod {
return CommsEmailTemplateModFunc(func(_ context.Context, o *CommsEmailTemplateTemplate) {
o.ContentHashTXT = f
})
}
// Clear any values for the column
func (m commsEmailTemplateMods) UnsetContentHashTXT() CommsEmailTemplateMod {
return CommsEmailTemplateModFunc(func(_ context.Context, o *CommsEmailTemplateTemplate) {
o.ContentHashTXT = nil
})
}
// Generates a random value for the column using the given faker
// if faker is nil, a default faker is used
func (m commsEmailTemplateMods) RandomContentHashTXT(f *faker.Faker) CommsEmailTemplateMod {
return CommsEmailTemplateModFunc(func(_ context.Context, o *CommsEmailTemplateTemplate) {
o.ContentHashTXT = func() string {
return random_string(f, "64")
}
})
}
// Set the model columns to this value
func (m commsEmailTemplateMods) Created(val time.Time) CommsEmailTemplateMod {
return CommsEmailTemplateModFunc(func(_ context.Context, o *CommsEmailTemplateTemplate) {
o.Created = func() time.Time { return val }
})
}
// Set the Column from the function
func (m commsEmailTemplateMods) CreatedFunc(f func() time.Time) CommsEmailTemplateMod {
return CommsEmailTemplateModFunc(func(_ context.Context, o *CommsEmailTemplateTemplate) {
o.Created = f
})
}
// Clear any values for the column
func (m commsEmailTemplateMods) UnsetCreated() CommsEmailTemplateMod {
return CommsEmailTemplateModFunc(func(_ context.Context, o *CommsEmailTemplateTemplate) {
o.Created = nil
})
}
// Generates a random value for the column using the given faker
// if faker is nil, a default faker is used
func (m commsEmailTemplateMods) RandomCreated(f *faker.Faker) CommsEmailTemplateMod {
return CommsEmailTemplateModFunc(func(_ context.Context, o *CommsEmailTemplateTemplate) {
o.Created = func() time.Time {
return random_time_Time(f)
}
})
}
// Set the model columns to this value
func (m commsEmailTemplateMods) ID(val int32) CommsEmailTemplateMod {
return CommsEmailTemplateModFunc(func(_ context.Context, o *CommsEmailTemplateTemplate) {
o.ID = func() int32 { return val }
})
}
// Set the Column from the function
func (m commsEmailTemplateMods) IDFunc(f func() int32) CommsEmailTemplateMod {
return CommsEmailTemplateModFunc(func(_ context.Context, o *CommsEmailTemplateTemplate) {
o.ID = f
})
}
// Clear any values for the column
func (m commsEmailTemplateMods) UnsetID() CommsEmailTemplateMod {
return CommsEmailTemplateModFunc(func(_ context.Context, o *CommsEmailTemplateTemplate) {
o.ID = nil
})
}
// Generates a random value for the column using the given faker
// if faker is nil, a default faker is used
func (m commsEmailTemplateMods) RandomID(f *faker.Faker) CommsEmailTemplateMod {
return CommsEmailTemplateModFunc(func(_ context.Context, o *CommsEmailTemplateTemplate) {
o.ID = func() int32 {
return random_int32(f)
}
})
}
// Set the model columns to this value
func (m commsEmailTemplateMods) Superceded(val null.Val[time.Time]) CommsEmailTemplateMod {
return CommsEmailTemplateModFunc(func(_ context.Context, o *CommsEmailTemplateTemplate) {
o.Superceded = func() null.Val[time.Time] { return val }
})
}
// Set the Column from the function
func (m commsEmailTemplateMods) SupercededFunc(f func() null.Val[time.Time]) CommsEmailTemplateMod {
return CommsEmailTemplateModFunc(func(_ context.Context, o *CommsEmailTemplateTemplate) {
o.Superceded = f
})
}
// Clear any values for the column
func (m commsEmailTemplateMods) UnsetSuperceded() CommsEmailTemplateMod {
return CommsEmailTemplateModFunc(func(_ context.Context, o *CommsEmailTemplateTemplate) {
o.Superceded = nil
})
}
// Generates a random value for the column using the given faker
// if faker is nil, a default faker is used
// The generated value is sometimes null
func (m commsEmailTemplateMods) RandomSuperceded(f *faker.Faker) CommsEmailTemplateMod {
return CommsEmailTemplateModFunc(func(_ context.Context, o *CommsEmailTemplateTemplate) {
o.Superceded = func() null.Val[time.Time] {
if f == nil {
f = &defaultFaker
}
val := random_time_Time(f)
return null.From(val)
}
})
}
// Generates a random value for the column using the given faker
// if faker is nil, a default faker is used
// The generated value is never null
func (m commsEmailTemplateMods) RandomSupercededNotNull(f *faker.Faker) CommsEmailTemplateMod {
return CommsEmailTemplateModFunc(func(_ context.Context, o *CommsEmailTemplateTemplate) {
o.Superceded = func() null.Val[time.Time] {
if f == nil {
f = &defaultFaker
}
val := random_time_Time(f)
return null.From(val)
}
})
}
// Set the model columns to this value
func (m commsEmailTemplateMods) MessageType(val enums.CommsMessagetypeemail) CommsEmailTemplateMod {
return CommsEmailTemplateModFunc(func(_ context.Context, o *CommsEmailTemplateTemplate) {
o.MessageType = func() enums.CommsMessagetypeemail { return val }
})
}
// Set the Column from the function
func (m commsEmailTemplateMods) MessageTypeFunc(f func() enums.CommsMessagetypeemail) CommsEmailTemplateMod {
return CommsEmailTemplateModFunc(func(_ context.Context, o *CommsEmailTemplateTemplate) {
o.MessageType = f
})
}
// Clear any values for the column
func (m commsEmailTemplateMods) UnsetMessageType() CommsEmailTemplateMod {
return CommsEmailTemplateModFunc(func(_ context.Context, o *CommsEmailTemplateTemplate) {
o.MessageType = nil
})
}
// Generates a random value for the column using the given faker
// if faker is nil, a default faker is used
func (m commsEmailTemplateMods) RandomMessageType(f *faker.Faker) CommsEmailTemplateMod {
return CommsEmailTemplateModFunc(func(_ context.Context, o *CommsEmailTemplateTemplate) {
o.MessageType = func() enums.CommsMessagetypeemail {
return random_enums_CommsMessagetypeemail(f)
}
})
}
func (m commsEmailTemplateMods) WithParentsCascading() CommsEmailTemplateMod {
return CommsEmailTemplateModFunc(func(ctx context.Context, o *CommsEmailTemplateTemplate) {
if isDone, _ := commsEmailTemplateWithParentsCascadingCtx.Value(ctx); isDone {
return
}
ctx = commsEmailTemplateWithParentsCascadingCtx.WithValue(ctx, true)
})
}
func (m commsEmailTemplateMods) WithTemplateEmailLogs(number int, related *CommsEmailLogTemplate) CommsEmailTemplateMod {
return CommsEmailTemplateModFunc(func(ctx context.Context, o *CommsEmailTemplateTemplate) {
o.r.TemplateEmailLogs = []*commsEmailTemplateRTemplateEmailLogsR{{
number: number,
o: related,
}}
})
}
func (m commsEmailTemplateMods) WithNewTemplateEmailLogs(number int, mods ...CommsEmailLogMod) CommsEmailTemplateMod {
return CommsEmailTemplateModFunc(func(ctx context.Context, o *CommsEmailTemplateTemplate) {
related := o.f.NewCommsEmailLogWithContext(ctx, mods...)
m.WithTemplateEmailLogs(number, related).Apply(ctx, o)
})
}
func (m commsEmailTemplateMods) AddTemplateEmailLogs(number int, related *CommsEmailLogTemplate) CommsEmailTemplateMod {
return CommsEmailTemplateModFunc(func(ctx context.Context, o *CommsEmailTemplateTemplate) {
o.r.TemplateEmailLogs = append(o.r.TemplateEmailLogs, &commsEmailTemplateRTemplateEmailLogsR{
number: number,
o: related,
})
})
}
func (m commsEmailTemplateMods) AddNewTemplateEmailLogs(number int, mods ...CommsEmailLogMod) CommsEmailTemplateMod {
return CommsEmailTemplateModFunc(func(ctx context.Context, o *CommsEmailTemplateTemplate) {
related := o.f.NewCommsEmailLogWithContext(ctx, mods...)
m.AddTemplateEmailLogs(number, related).Apply(ctx, o)
})
}
func (m commsEmailTemplateMods) AddExistingTemplateEmailLogs(existingModels ...*models.CommsEmailLog) CommsEmailTemplateMod {
return CommsEmailTemplateModFunc(func(ctx context.Context, o *CommsEmailTemplateTemplate) {
for _, em := range existingModels {
o.r.TemplateEmailLogs = append(o.r.TemplateEmailLogs, &commsEmailTemplateRTemplateEmailLogsR{
o: o.f.FromExistingCommsEmailLog(em),
})
}
})
}
func (m commsEmailTemplateMods) WithoutTemplateEmailLogs() CommsEmailTemplateMod {
return CommsEmailTemplateModFunc(func(ctx context.Context, o *CommsEmailTemplateTemplate) {
o.r.TemplateEmailLogs = nil
})
}

View file

@ -44,15 +44,10 @@ type CommsPhoneTemplate struct {
}
type commsPhoneR struct {
SourceEmailLogs []*commsPhoneRSourceEmailLogsR
DestinationTextLogs []*commsPhoneRDestinationTextLogsR
SourceTextLogs []*commsPhoneRSourceTextLogsR
}
type commsPhoneRSourceEmailLogsR struct {
number int
o *CommsEmailLogTemplate
}
type commsPhoneRDestinationTextLogsR struct {
number int
o *CommsTextLogTemplate
@ -72,19 +67,6 @@ func (o *CommsPhoneTemplate) Apply(ctx context.Context, mods ...CommsPhoneMod) {
// setModelRels creates and sets the relationships on *models.CommsPhone
// according to the relationships in the template. Nothing is inserted into the db
func (t CommsPhoneTemplate) setModelRels(o *models.CommsPhone) {
if t.r.SourceEmailLogs != nil {
rel := models.CommsEmailLogSlice{}
for _, r := range t.r.SourceEmailLogs {
related := r.o.BuildMany(r.number)
for _, rel := range related {
rel.Source = o.E164 // h2
rel.R.SourcePhone = o
}
rel = append(rel, related...)
}
o.R.SourceEmailLogs = rel
}
if t.r.DestinationTextLogs != nil {
rel := models.CommsTextLogSlice{}
for _, r := range t.r.DestinationTextLogs {
@ -189,26 +171,6 @@ func ensureCreatableCommsPhone(m *models.CommsPhoneSetter) {
func (o *CommsPhoneTemplate) insertOptRels(ctx context.Context, exec bob.Executor, m *models.CommsPhone) error {
var err error
isSourceEmailLogsDone, _ := commsPhoneRelSourceEmailLogsCtx.Value(ctx)
if !isSourceEmailLogsDone && o.r.SourceEmailLogs != nil {
ctx = commsPhoneRelSourceEmailLogsCtx.WithValue(ctx, true)
for _, r := range o.r.SourceEmailLogs {
if r.o.alreadyPersisted {
m.R.SourceEmailLogs = append(m.R.SourceEmailLogs, r.o.Build())
} else {
rel0, err := r.o.CreateMany(ctx, exec, r.number)
if err != nil {
return err
}
err = m.AttachSourceEmailLogs(ctx, exec, rel0...)
if err != nil {
return err
}
}
}
}
isDestinationTextLogsDone, _ := commsPhoneRelDestinationTextLogsCtx.Value(ctx)
if !isDestinationTextLogsDone && o.r.DestinationTextLogs != nil {
ctx = commsPhoneRelDestinationTextLogsCtx.WithValue(ctx, true)
@ -216,12 +178,12 @@ func (o *CommsPhoneTemplate) insertOptRels(ctx context.Context, exec bob.Executo
if r.o.alreadyPersisted {
m.R.DestinationTextLogs = append(m.R.DestinationTextLogs, r.o.Build())
} else {
rel1, err := r.o.CreateMany(ctx, exec, r.number)
rel0, err := r.o.CreateMany(ctx, exec, r.number)
if err != nil {
return err
}
err = m.AttachDestinationTextLogs(ctx, exec, rel1...)
err = m.AttachDestinationTextLogs(ctx, exec, rel0...)
if err != nil {
return err
}
@ -236,12 +198,12 @@ func (o *CommsPhoneTemplate) insertOptRels(ctx context.Context, exec bob.Executo
if r.o.alreadyPersisted {
m.R.SourceTextLogs = append(m.R.SourceTextLogs, r.o.Build())
} else {
rel2, err := r.o.CreateMany(ctx, exec, r.number)
rel1, err := r.o.CreateMany(ctx, exec, r.number)
if err != nil {
return err
}
err = m.AttachSourceTextLogs(ctx, exec, rel2...)
err = m.AttachSourceTextLogs(ctx, exec, rel1...)
if err != nil {
return err
}
@ -417,54 +379,6 @@ func (m commsPhoneMods) WithParentsCascading() CommsPhoneMod {
})
}
func (m commsPhoneMods) WithSourceEmailLogs(number int, related *CommsEmailLogTemplate) CommsPhoneMod {
return CommsPhoneModFunc(func(ctx context.Context, o *CommsPhoneTemplate) {
o.r.SourceEmailLogs = []*commsPhoneRSourceEmailLogsR{{
number: number,
o: related,
}}
})
}
func (m commsPhoneMods) WithNewSourceEmailLogs(number int, mods ...CommsEmailLogMod) CommsPhoneMod {
return CommsPhoneModFunc(func(ctx context.Context, o *CommsPhoneTemplate) {
related := o.f.NewCommsEmailLogWithContext(ctx, mods...)
m.WithSourceEmailLogs(number, related).Apply(ctx, o)
})
}
func (m commsPhoneMods) AddSourceEmailLogs(number int, related *CommsEmailLogTemplate) CommsPhoneMod {
return CommsPhoneModFunc(func(ctx context.Context, o *CommsPhoneTemplate) {
o.r.SourceEmailLogs = append(o.r.SourceEmailLogs, &commsPhoneRSourceEmailLogsR{
number: number,
o: related,
})
})
}
func (m commsPhoneMods) AddNewSourceEmailLogs(number int, mods ...CommsEmailLogMod) CommsPhoneMod {
return CommsPhoneModFunc(func(ctx context.Context, o *CommsPhoneTemplate) {
related := o.f.NewCommsEmailLogWithContext(ctx, mods...)
m.AddSourceEmailLogs(number, related).Apply(ctx, o)
})
}
func (m commsPhoneMods) AddExistingSourceEmailLogs(existingModels ...*models.CommsEmailLog) CommsPhoneMod {
return CommsPhoneModFunc(func(ctx context.Context, o *CommsPhoneTemplate) {
for _, em := range existingModels {
o.r.SourceEmailLogs = append(o.r.SourceEmailLogs, &commsPhoneRSourceEmailLogsR{
o: o.f.FromExistingCommsEmailLog(em),
})
}
})
}
func (m commsPhoneMods) WithoutSourceEmailLogs() CommsPhoneMod {
return CommsPhoneModFunc(func(ctx context.Context, o *CommsPhoneTemplate) {
o.r.SourceEmailLogs = nil
})
}
func (m commsPhoneMods) WithDestinationTextLogs(number int, related *CommsTextLogTemplate) CommsPhoneMod {
return CommsPhoneModFunc(func(ctx context.Context, o *CommsPhoneTemplate) {
o.r.DestinationTextLogs = []*commsPhoneRDestinationTextLogsR{{

View file

@ -0,0 +1,44 @@
-- +goose Up
-- CREATE EXTENSION IF NOT EXISTS hstore;
ALTER TABLE comms.email RENAME TO email_contact;
ALTER TABLE comms.email_contact ADD COLUMN public_id TEXT;
UPDATE comms.email_contact SET public_id = '';
ALTER TABLE comms.email_contact ALTER COLUMN public_id SET NOT NULL;
CREATE TABLE comms.email_template (
content_html TEXT NOT NULL,
content_txt TEXT NOT NULL,
content_hash_html VARCHAR(64) NOT NULL,
content_hash_txt VARCHAR(64) NOT NULL,
created TIMESTAMP WITHOUT TIME ZONE NOT NULL,
id SERIAL NOT NULL,
superceded TIMESTAMP WITHOUT TIME ZONE,
message_type comms.MessageTypeEmail NOT NULL,
PRIMARY KEY (id)
);
DROP TABLE comms.email_log;
CREATE TABLE comms.email_log (
id SERIAL,
created TIMESTAMP WITHOUT TIME ZONE NOT NULL,
delivery_status VARCHAR(16) NOT NULL,
destination TEXT NOT NULL REFERENCES comms.email_contact(address),
public_id VARCHAR(64) NOT NULL,
sent_at TIMESTAMP WITHOUT TIME ZONE,
source TEXT NOT NULL,
subject VARCHAR(255) NOT NULL,
template_id INTEGER REFERENCES comms.email_template(id),
template_data HSTORE NOT NULL,
type comms.MessageTypeEmail NOT NULL,
PRIMARY KEY (id)
);
-- +goose Down
DROP TABLE comms.email_log;
CREATE TABLE comms.email_log (
created TIMESTAMP WITHOUT TIME ZONE NOT NULL,
destination TEXT NOT NULL REFERENCES comms.email_contact(address),
source TEXT NOT NULL REFERENCES comms.phone(e164),
type comms.MessageTypeEmail NOT NULL,
PRIMARY KEY(destination, source, type)
);
DROP TABLE comms.email_template;
ALTER TABLE comms.email_contact DROP COLUMN public_id;
ALTER TABLE comms.email_contact RENAME TO email;

View file

@ -21,58 +21,62 @@ var (
)
type preloadCounts struct {
ArcgisUser arcgisuserCountPreloader
CommsEmail commsEmailCountPreloader
CommsPhone commsPhoneCountPreloader
NoteAudio noteAudioCountPreloader
NoteImage noteImageCountPreloader
Organization organizationCountPreloader
PublicreportImage publicreportImageCountPreloader
PublicreportPool publicreportPoolCountPreloader
PublicreportQuick publicreportQuickCountPreloader
User userCountPreloader
ArcgisUser arcgisuserCountPreloader
CommsEmailContact commsEmailContactCountPreloader
CommsEmailTemplate commsEmailTemplateCountPreloader
CommsPhone commsPhoneCountPreloader
NoteAudio noteAudioCountPreloader
NoteImage noteImageCountPreloader
Organization organizationCountPreloader
PublicreportImage publicreportImageCountPreloader
PublicreportPool publicreportPoolCountPreloader
PublicreportQuick publicreportQuickCountPreloader
User userCountPreloader
}
func getPreloadCount() preloadCounts {
return preloadCounts{
ArcgisUser: buildArcgisUserCountPreloader(),
CommsEmail: buildCommsEmailCountPreloader(),
CommsPhone: buildCommsPhoneCountPreloader(),
NoteAudio: buildNoteAudioCountPreloader(),
NoteImage: buildNoteImageCountPreloader(),
Organization: buildOrganizationCountPreloader(),
PublicreportImage: buildPublicreportImageCountPreloader(),
PublicreportPool: buildPublicreportPoolCountPreloader(),
PublicreportQuick: buildPublicreportQuickCountPreloader(),
User: buildUserCountPreloader(),
ArcgisUser: buildArcgisUserCountPreloader(),
CommsEmailContact: buildCommsEmailContactCountPreloader(),
CommsEmailTemplate: buildCommsEmailTemplateCountPreloader(),
CommsPhone: buildCommsPhoneCountPreloader(),
NoteAudio: buildNoteAudioCountPreloader(),
NoteImage: buildNoteImageCountPreloader(),
Organization: buildOrganizationCountPreloader(),
PublicreportImage: buildPublicreportImageCountPreloader(),
PublicreportPool: buildPublicreportPoolCountPreloader(),
PublicreportQuick: buildPublicreportQuickCountPreloader(),
User: buildUserCountPreloader(),
}
}
type thenLoadCounts[Q orm.Loadable] struct {
ArcgisUser arcgisuserCountThenLoader[Q]
CommsEmail commsEmailCountThenLoader[Q]
CommsPhone commsPhoneCountThenLoader[Q]
NoteAudio noteAudioCountThenLoader[Q]
NoteImage noteImageCountThenLoader[Q]
Organization organizationCountThenLoader[Q]
PublicreportImage publicreportImageCountThenLoader[Q]
PublicreportPool publicreportPoolCountThenLoader[Q]
PublicreportQuick publicreportQuickCountThenLoader[Q]
User userCountThenLoader[Q]
ArcgisUser arcgisuserCountThenLoader[Q]
CommsEmailContact commsEmailContactCountThenLoader[Q]
CommsEmailTemplate commsEmailTemplateCountThenLoader[Q]
CommsPhone commsPhoneCountThenLoader[Q]
NoteAudio noteAudioCountThenLoader[Q]
NoteImage noteImageCountThenLoader[Q]
Organization organizationCountThenLoader[Q]
PublicreportImage publicreportImageCountThenLoader[Q]
PublicreportPool publicreportPoolCountThenLoader[Q]
PublicreportQuick publicreportQuickCountThenLoader[Q]
User userCountThenLoader[Q]
}
func getThenLoadCount[Q orm.Loadable]() thenLoadCounts[Q] {
return thenLoadCounts[Q]{
ArcgisUser: buildArcgisUserCountThenLoader[Q](),
CommsEmail: buildCommsEmailCountThenLoader[Q](),
CommsPhone: buildCommsPhoneCountThenLoader[Q](),
NoteAudio: buildNoteAudioCountThenLoader[Q](),
NoteImage: buildNoteImageCountThenLoader[Q](),
Organization: buildOrganizationCountThenLoader[Q](),
PublicreportImage: buildPublicreportImageCountThenLoader[Q](),
PublicreportPool: buildPublicreportPoolCountThenLoader[Q](),
PublicreportQuick: buildPublicreportQuickCountThenLoader[Q](),
User: buildUserCountThenLoader[Q](),
ArcgisUser: buildArcgisUserCountThenLoader[Q](),
CommsEmailContact: buildCommsEmailContactCountThenLoader[Q](),
CommsEmailTemplate: buildCommsEmailTemplateCountThenLoader[Q](),
CommsPhone: buildCommsPhoneCountThenLoader[Q](),
NoteAudio: buildNoteAudioCountThenLoader[Q](),
NoteImage: buildNoteImageCountThenLoader[Q](),
Organization: buildOrganizationCountThenLoader[Q](),
PublicreportImage: buildPublicreportImageCountThenLoader[Q](),
PublicreportPool: buildPublicreportPoolCountThenLoader[Q](),
PublicreportQuick: buildPublicreportQuickCountThenLoader[Q](),
User: buildUserCountThenLoader[Q](),
}
}

View file

@ -34,8 +34,9 @@ func (j joinSet[Q]) AliasedAs(alias string) joinSet[Q] {
type joins[Q dialect.Joinable] struct {
ArcgisUsers joinSet[arcgisuserJoins[Q]]
ArcgisUserPrivileges joinSet[arcgisUserPrivilegeJoins[Q]]
CommsEmails joinSet[commsEmailJoins[Q]]
CommsEmailContacts joinSet[commsEmailContactJoins[Q]]
CommsEmailLogs joinSet[commsEmailLogJoins[Q]]
CommsEmailTemplates joinSet[commsEmailTemplateJoins[Q]]
CommsPhones joinSet[commsPhoneJoins[Q]]
CommsTextLogs joinSet[commsTextLogJoins[Q]]
FieldseekerContainerrelates joinSet[fieldseekerContainerrelateJoins[Q]]
@ -99,8 +100,9 @@ func getJoins[Q dialect.Joinable]() joins[Q] {
return joins[Q]{
ArcgisUsers: buildJoinSet[arcgisuserJoins[Q]](ArcgisUsers.Columns, buildArcgisUserJoins),
ArcgisUserPrivileges: buildJoinSet[arcgisUserPrivilegeJoins[Q]](ArcgisUserPrivileges.Columns, buildArcgisUserPrivilegeJoins),
CommsEmails: buildJoinSet[commsEmailJoins[Q]](CommsEmails.Columns, buildCommsEmailJoins),
CommsEmailContacts: buildJoinSet[commsEmailContactJoins[Q]](CommsEmailContacts.Columns, buildCommsEmailContactJoins),
CommsEmailLogs: buildJoinSet[commsEmailLogJoins[Q]](CommsEmailLogs.Columns, buildCommsEmailLogJoins),
CommsEmailTemplates: buildJoinSet[commsEmailTemplateJoins[Q]](CommsEmailTemplates.Columns, buildCommsEmailTemplateJoins),
CommsPhones: buildJoinSet[commsPhoneJoins[Q]](CommsPhones.Columns, buildCommsPhoneJoins),
CommsTextLogs: buildJoinSet[commsTextLogJoins[Q]](CommsTextLogs.Columns, buildCommsTextLogJoins),
FieldseekerContainerrelates: buildJoinSet[fieldseekerContainerrelateJoins[Q]](FieldseekerContainerrelates.Columns, buildFieldseekerContainerrelateJoins),

View file

@ -19,8 +19,9 @@ var Preload = getPreloaders()
type preloaders struct {
ArcgisUser arcgisuserPreloader
ArcgisUserPrivilege arcgisUserPrivilegePreloader
CommsEmail commsEmailPreloader
CommsEmailContact commsEmailContactPreloader
CommsEmailLog commsEmailLogPreloader
CommsEmailTemplate commsEmailTemplatePreloader
CommsPhone commsPhonePreloader
CommsTextLog commsTextLogPreloader
FieldseekerContainerrelate fieldseekerContainerrelatePreloader
@ -76,8 +77,9 @@ func getPreloaders() preloaders {
return preloaders{
ArcgisUser: buildArcgisUserPreloader(),
ArcgisUserPrivilege: buildArcgisUserPrivilegePreloader(),
CommsEmail: buildCommsEmailPreloader(),
CommsEmailContact: buildCommsEmailContactPreloader(),
CommsEmailLog: buildCommsEmailLogPreloader(),
CommsEmailTemplate: buildCommsEmailTemplatePreloader(),
CommsPhone: buildCommsPhonePreloader(),
CommsTextLog: buildCommsTextLogPreloader(),
FieldseekerContainerrelate: buildFieldseekerContainerrelatePreloader(),
@ -139,8 +141,9 @@ var (
type thenLoaders[Q orm.Loadable] struct {
ArcgisUser arcgisuserThenLoader[Q]
ArcgisUserPrivilege arcgisUserPrivilegeThenLoader[Q]
CommsEmail commsEmailThenLoader[Q]
CommsEmailContact commsEmailContactThenLoader[Q]
CommsEmailLog commsEmailLogThenLoader[Q]
CommsEmailTemplate commsEmailTemplateThenLoader[Q]
CommsPhone commsPhoneThenLoader[Q]
CommsTextLog commsTextLogThenLoader[Q]
FieldseekerContainerrelate fieldseekerContainerrelateThenLoader[Q]
@ -196,8 +199,9 @@ func getThenLoaders[Q orm.Loadable]() thenLoaders[Q] {
return thenLoaders[Q]{
ArcgisUser: buildArcgisUserThenLoader[Q](),
ArcgisUserPrivilege: buildArcgisUserPrivilegeThenLoader[Q](),
CommsEmail: buildCommsEmailThenLoader[Q](),
CommsEmailContact: buildCommsEmailContactThenLoader[Q](),
CommsEmailLog: buildCommsEmailLogThenLoader[Q](),
CommsEmailTemplate: buildCommsEmailTemplateThenLoader[Q](),
CommsPhone: buildCommsPhoneThenLoader[Q](),
CommsTextLog: buildCommsTextLogThenLoader[Q](),
FieldseekerContainerrelate: buildFieldseekerContainerrelateThenLoader[Q](),

View file

@ -19,8 +19,9 @@ var (
func Where[Q psql.Filterable]() struct {
ArcgisUsers arcgisuserWhere[Q]
ArcgisUserPrivileges arcgisUserPrivilegeWhere[Q]
CommsEmails commsEmailWhere[Q]
CommsEmailContacts commsEmailContactWhere[Q]
CommsEmailLogs commsEmailLogWhere[Q]
CommsEmailTemplates commsEmailTemplateWhere[Q]
CommsPhones commsPhoneWhere[Q]
CommsTextLogs commsTextLogWhere[Q]
FieldseekerContainerrelates fieldseekerContainerrelateWhere[Q]
@ -82,8 +83,9 @@ func Where[Q psql.Filterable]() struct {
return struct {
ArcgisUsers arcgisuserWhere[Q]
ArcgisUserPrivileges arcgisUserPrivilegeWhere[Q]
CommsEmails commsEmailWhere[Q]
CommsEmailContacts commsEmailContactWhere[Q]
CommsEmailLogs commsEmailLogWhere[Q]
CommsEmailTemplates commsEmailTemplateWhere[Q]
CommsPhones commsPhoneWhere[Q]
CommsTextLogs commsTextLogWhere[Q]
FieldseekerContainerrelates fieldseekerContainerrelateWhere[Q]
@ -144,8 +146,9 @@ func Where[Q psql.Filterable]() struct {
}{
ArcgisUsers: buildArcgisUserWhere[Q](ArcgisUsers.Columns),
ArcgisUserPrivileges: buildArcgisUserPrivilegeWhere[Q](ArcgisUserPrivileges.Columns),
CommsEmails: buildCommsEmailWhere[Q](CommsEmails.Columns),
CommsEmailContacts: buildCommsEmailContactWhere[Q](CommsEmailContacts.Columns),
CommsEmailLogs: buildCommsEmailLogWhere[Q](CommsEmailLogs.Columns),
CommsEmailTemplates: buildCommsEmailTemplateWhere[Q](CommsEmailTemplates.Columns),
CommsPhones: buildCommsPhoneWhere[Q](CommsPhones.Columns),
CommsTextLogs: buildCommsTextLogWhere[Q](CommsTextLogs.Columns),
FieldseekerContainerrelates: buildFieldseekerContainerrelateWhere[Q](FieldseekerContainerrelates.Columns),

View file

@ -1,737 +0,0 @@
// Code generated by BobGen psql v0.42.1. DO NOT EDIT.
// This file is meant to be re-generated in place and/or deleted at any time.
package models
import (
"context"
"fmt"
"io"
"github.com/aarondl/opt/omit"
"github.com/stephenafamo/bob"
"github.com/stephenafamo/bob/dialect/psql"
"github.com/stephenafamo/bob/dialect/psql/dialect"
"github.com/stephenafamo/bob/dialect/psql/dm"
"github.com/stephenafamo/bob/dialect/psql/sm"
"github.com/stephenafamo/bob/dialect/psql/um"
"github.com/stephenafamo/bob/expr"
"github.com/stephenafamo/bob/mods"
"github.com/stephenafamo/bob/orm"
"github.com/stephenafamo/bob/types/pgtypes"
)
// CommsEmail is an object representing the database table.
type CommsEmail struct {
Address string `db:"address,pk" `
Confirmed bool `db:"confirmed" `
IsSubscribed bool `db:"is_subscribed" `
R commsEmailR `db:"-" `
C commsEmailC `db:"-" `
}
// CommsEmailSlice is an alias for a slice of pointers to CommsEmail.
// This should almost always be used instead of []*CommsEmail.
type CommsEmailSlice []*CommsEmail
// CommsEmails contains methods to work with the email table
var CommsEmails = psql.NewTablex[*CommsEmail, CommsEmailSlice, *CommsEmailSetter]("comms", "email", buildCommsEmailColumns("comms.email"))
// CommsEmailsQuery is a query on the email table
type CommsEmailsQuery = *psql.ViewQuery[*CommsEmail, CommsEmailSlice]
// commsEmailR is where relationships are stored.
type commsEmailR struct {
DestinationEmailLogs CommsEmailLogSlice // comms.email_log.email_log_destination_fkey
}
func buildCommsEmailColumns(alias string) commsEmailColumns {
return commsEmailColumns{
ColumnsExpr: expr.NewColumnsExpr(
"address", "confirmed", "is_subscribed",
).WithParent("comms.email"),
tableAlias: alias,
Address: psql.Quote(alias, "address"),
Confirmed: psql.Quote(alias, "confirmed"),
IsSubscribed: psql.Quote(alias, "is_subscribed"),
}
}
type commsEmailColumns struct {
expr.ColumnsExpr
tableAlias string
Address psql.Expression
Confirmed psql.Expression
IsSubscribed psql.Expression
}
func (c commsEmailColumns) Alias() string {
return c.tableAlias
}
func (commsEmailColumns) AliasedAs(alias string) commsEmailColumns {
return buildCommsEmailColumns(alias)
}
// CommsEmailSetter is used for insert/upsert/update operations
// All values are optional, and do not have to be set
// Generated columns are not included
type CommsEmailSetter struct {
Address omit.Val[string] `db:"address,pk" `
Confirmed omit.Val[bool] `db:"confirmed" `
IsSubscribed omit.Val[bool] `db:"is_subscribed" `
}
func (s CommsEmailSetter) SetColumns() []string {
vals := make([]string, 0, 3)
if s.Address.IsValue() {
vals = append(vals, "address")
}
if s.Confirmed.IsValue() {
vals = append(vals, "confirmed")
}
if s.IsSubscribed.IsValue() {
vals = append(vals, "is_subscribed")
}
return vals
}
func (s CommsEmailSetter) Overwrite(t *CommsEmail) {
if s.Address.IsValue() {
t.Address = s.Address.MustGet()
}
if s.Confirmed.IsValue() {
t.Confirmed = s.Confirmed.MustGet()
}
if s.IsSubscribed.IsValue() {
t.IsSubscribed = s.IsSubscribed.MustGet()
}
}
func (s *CommsEmailSetter) Apply(q *dialect.InsertQuery) {
q.AppendHooks(func(ctx context.Context, exec bob.Executor) (context.Context, error) {
return CommsEmails.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, 3)
if s.Address.IsValue() {
vals[0] = psql.Arg(s.Address.MustGet())
} else {
vals[0] = psql.Raw("DEFAULT")
}
if s.Confirmed.IsValue() {
vals[1] = psql.Arg(s.Confirmed.MustGet())
} else {
vals[1] = psql.Raw("DEFAULT")
}
if s.IsSubscribed.IsValue() {
vals[2] = psql.Arg(s.IsSubscribed.MustGet())
} else {
vals[2] = psql.Raw("DEFAULT")
}
return bob.ExpressSlice(ctx, w, d, start, vals, "", ", ", "")
}))
}
func (s CommsEmailSetter) UpdateMod() bob.Mod[*dialect.UpdateQuery] {
return um.Set(s.Expressions()...)
}
func (s CommsEmailSetter) Expressions(prefix ...string) []bob.Expression {
exprs := make([]bob.Expression, 0, 3)
if s.Address.IsValue() {
exprs = append(exprs, expr.Join{Sep: " = ", Exprs: []bob.Expression{
psql.Quote(append(prefix, "address")...),
psql.Arg(s.Address),
}})
}
if s.Confirmed.IsValue() {
exprs = append(exprs, expr.Join{Sep: " = ", Exprs: []bob.Expression{
psql.Quote(append(prefix, "confirmed")...),
psql.Arg(s.Confirmed),
}})
}
if s.IsSubscribed.IsValue() {
exprs = append(exprs, expr.Join{Sep: " = ", Exprs: []bob.Expression{
psql.Quote(append(prefix, "is_subscribed")...),
psql.Arg(s.IsSubscribed),
}})
}
return exprs
}
// FindCommsEmail retrieves a single record by primary key
// If cols is empty Find will return all columns.
func FindCommsEmail(ctx context.Context, exec bob.Executor, AddressPK string, cols ...string) (*CommsEmail, error) {
if len(cols) == 0 {
return CommsEmails.Query(
sm.Where(CommsEmails.Columns.Address.EQ(psql.Arg(AddressPK))),
).One(ctx, exec)
}
return CommsEmails.Query(
sm.Where(CommsEmails.Columns.Address.EQ(psql.Arg(AddressPK))),
sm.Columns(CommsEmails.Columns.Only(cols...)),
).One(ctx, exec)
}
// CommsEmailExists checks the presence of a single record by primary key
func CommsEmailExists(ctx context.Context, exec bob.Executor, AddressPK string) (bool, error) {
return CommsEmails.Query(
sm.Where(CommsEmails.Columns.Address.EQ(psql.Arg(AddressPK))),
).Exists(ctx, exec)
}
// AfterQueryHook is called after CommsEmail is retrieved from the database
func (o *CommsEmail) AfterQueryHook(ctx context.Context, exec bob.Executor, queryType bob.QueryType) error {
var err error
switch queryType {
case bob.QueryTypeSelect:
ctx, err = CommsEmails.AfterSelectHooks.RunHooks(ctx, exec, CommsEmailSlice{o})
case bob.QueryTypeInsert:
ctx, err = CommsEmails.AfterInsertHooks.RunHooks(ctx, exec, CommsEmailSlice{o})
case bob.QueryTypeUpdate:
ctx, err = CommsEmails.AfterUpdateHooks.RunHooks(ctx, exec, CommsEmailSlice{o})
case bob.QueryTypeDelete:
ctx, err = CommsEmails.AfterDeleteHooks.RunHooks(ctx, exec, CommsEmailSlice{o})
}
return err
}
// primaryKeyVals returns the primary key values of the CommsEmail
func (o *CommsEmail) primaryKeyVals() bob.Expression {
return psql.Arg(o.Address)
}
func (o *CommsEmail) pkEQ() dialect.Expression {
return psql.Quote("comms.email", "address").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 CommsEmail
func (o *CommsEmail) Update(ctx context.Context, exec bob.Executor, s *CommsEmailSetter) error {
v, err := CommsEmails.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 CommsEmail record with an executor
func (o *CommsEmail) Delete(ctx context.Context, exec bob.Executor) error {
_, err := CommsEmails.Delete(dm.Where(o.pkEQ())).Exec(ctx, exec)
return err
}
// Reload refreshes the CommsEmail using the executor
func (o *CommsEmail) Reload(ctx context.Context, exec bob.Executor) error {
o2, err := CommsEmails.Query(
sm.Where(CommsEmails.Columns.Address.EQ(psql.Arg(o.Address))),
).One(ctx, exec)
if err != nil {
return err
}
o2.R = o.R
*o = *o2
return nil
}
// AfterQueryHook is called after CommsEmailSlice is retrieved from the database
func (o CommsEmailSlice) AfterQueryHook(ctx context.Context, exec bob.Executor, queryType bob.QueryType) error {
var err error
switch queryType {
case bob.QueryTypeSelect:
ctx, err = CommsEmails.AfterSelectHooks.RunHooks(ctx, exec, o)
case bob.QueryTypeInsert:
ctx, err = CommsEmails.AfterInsertHooks.RunHooks(ctx, exec, o)
case bob.QueryTypeUpdate:
ctx, err = CommsEmails.AfterUpdateHooks.RunHooks(ctx, exec, o)
case bob.QueryTypeDelete:
ctx, err = CommsEmails.AfterDeleteHooks.RunHooks(ctx, exec, o)
}
return err
}
func (o CommsEmailSlice) pkIN() dialect.Expression {
if len(o) == 0 {
return psql.Raw("NULL")
}
return psql.Quote("comms.email", "address").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 CommsEmailSlice) copyMatchingRows(from ...*CommsEmail) {
for i, old := range o {
for _, new := range from {
if new.Address != old.Address {
continue
}
new.R = old.R
o[i] = new
break
}
}
}
// UpdateMod modifies an update query with "WHERE primary_key IN (o...)"
func (o CommsEmailSlice) 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 CommsEmails.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 *CommsEmail:
o.copyMatchingRows(retrieved)
case []*CommsEmail:
o.copyMatchingRows(retrieved...)
case CommsEmailSlice:
o.copyMatchingRows(retrieved...)
default:
// If the retrieved value is not a CommsEmail or a slice of CommsEmail
// then run the AfterUpdateHooks on the slice
_, err = CommsEmails.AfterUpdateHooks.RunHooks(ctx, exec, o)
}
return err
}))
q.AppendWhere(o.pkIN())
})
}
// DeleteMod modifies an delete query with "WHERE primary_key IN (o...)"
func (o CommsEmailSlice) 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 CommsEmails.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 *CommsEmail:
o.copyMatchingRows(retrieved)
case []*CommsEmail:
o.copyMatchingRows(retrieved...)
case CommsEmailSlice:
o.copyMatchingRows(retrieved...)
default:
// If the retrieved value is not a CommsEmail or a slice of CommsEmail
// then run the AfterDeleteHooks on the slice
_, err = CommsEmails.AfterDeleteHooks.RunHooks(ctx, exec, o)
}
return err
}))
q.AppendWhere(o.pkIN())
})
}
func (o CommsEmailSlice) UpdateAll(ctx context.Context, exec bob.Executor, vals CommsEmailSetter) error {
if len(o) == 0 {
return nil
}
_, err := CommsEmails.Update(vals.UpdateMod(), o.UpdateMod()).All(ctx, exec)
return err
}
func (o CommsEmailSlice) DeleteAll(ctx context.Context, exec bob.Executor) error {
if len(o) == 0 {
return nil
}
_, err := CommsEmails.Delete(o.DeleteMod()).Exec(ctx, exec)
return err
}
func (o CommsEmailSlice) ReloadAll(ctx context.Context, exec bob.Executor) error {
if len(o) == 0 {
return nil
}
o2, err := CommsEmails.Query(sm.Where(o.pkIN())).All(ctx, exec)
if err != nil {
return err
}
o.copyMatchingRows(o2...)
return nil
}
// DestinationEmailLogs starts a query for related objects on comms.email_log
func (o *CommsEmail) DestinationEmailLogs(mods ...bob.Mod[*dialect.SelectQuery]) CommsEmailLogsQuery {
return CommsEmailLogs.Query(append(mods,
sm.Where(CommsEmailLogs.Columns.Destination.EQ(psql.Arg(o.Address))),
)...)
}
func (os CommsEmailSlice) DestinationEmailLogs(mods ...bob.Mod[*dialect.SelectQuery]) CommsEmailLogsQuery {
pkAddress := make(pgtypes.Array[string], 0, len(os))
for _, o := range os {
if o == nil {
continue
}
pkAddress = append(pkAddress, o.Address)
}
PKArgExpr := psql.Select(sm.Columns(
psql.F("unnest", psql.Cast(psql.Arg(pkAddress), "text[]")),
))
return CommsEmailLogs.Query(append(mods,
sm.Where(psql.Group(CommsEmailLogs.Columns.Destination).OP("IN", PKArgExpr)),
)...)
}
func insertCommsEmailDestinationEmailLogs0(ctx context.Context, exec bob.Executor, commsEmailLogs1 []*CommsEmailLogSetter, commsEmail0 *CommsEmail) (CommsEmailLogSlice, error) {
for i := range commsEmailLogs1 {
commsEmailLogs1[i].Destination = omit.From(commsEmail0.Address)
}
ret, err := CommsEmailLogs.Insert(bob.ToMods(commsEmailLogs1...)).All(ctx, exec)
if err != nil {
return ret, fmt.Errorf("insertCommsEmailDestinationEmailLogs0: %w", err)
}
return ret, nil
}
func attachCommsEmailDestinationEmailLogs0(ctx context.Context, exec bob.Executor, count int, commsEmailLogs1 CommsEmailLogSlice, commsEmail0 *CommsEmail) (CommsEmailLogSlice, error) {
setter := &CommsEmailLogSetter{
Destination: omit.From(commsEmail0.Address),
}
err := commsEmailLogs1.UpdateAll(ctx, exec, *setter)
if err != nil {
return nil, fmt.Errorf("attachCommsEmailDestinationEmailLogs0: %w", err)
}
return commsEmailLogs1, nil
}
func (commsEmail0 *CommsEmail) InsertDestinationEmailLogs(ctx context.Context, exec bob.Executor, related ...*CommsEmailLogSetter) error {
if len(related) == 0 {
return nil
}
var err error
commsEmailLogs1, err := insertCommsEmailDestinationEmailLogs0(ctx, exec, related, commsEmail0)
if err != nil {
return err
}
commsEmail0.R.DestinationEmailLogs = append(commsEmail0.R.DestinationEmailLogs, commsEmailLogs1...)
for _, rel := range commsEmailLogs1 {
rel.R.DestinationEmail = commsEmail0
}
return nil
}
func (commsEmail0 *CommsEmail) AttachDestinationEmailLogs(ctx context.Context, exec bob.Executor, related ...*CommsEmailLog) error {
if len(related) == 0 {
return nil
}
var err error
commsEmailLogs1 := CommsEmailLogSlice(related)
_, err = attachCommsEmailDestinationEmailLogs0(ctx, exec, len(related), commsEmailLogs1, commsEmail0)
if err != nil {
return err
}
commsEmail0.R.DestinationEmailLogs = append(commsEmail0.R.DestinationEmailLogs, commsEmailLogs1...)
for _, rel := range related {
rel.R.DestinationEmail = commsEmail0
}
return nil
}
type commsEmailWhere[Q psql.Filterable] struct {
Address psql.WhereMod[Q, string]
Confirmed psql.WhereMod[Q, bool]
IsSubscribed psql.WhereMod[Q, bool]
}
func (commsEmailWhere[Q]) AliasedAs(alias string) commsEmailWhere[Q] {
return buildCommsEmailWhere[Q](buildCommsEmailColumns(alias))
}
func buildCommsEmailWhere[Q psql.Filterable](cols commsEmailColumns) commsEmailWhere[Q] {
return commsEmailWhere[Q]{
Address: psql.Where[Q, string](cols.Address),
Confirmed: psql.Where[Q, bool](cols.Confirmed),
IsSubscribed: psql.Where[Q, bool](cols.IsSubscribed),
}
}
func (o *CommsEmail) Preload(name string, retrieved any) error {
if o == nil {
return nil
}
switch name {
case "DestinationEmailLogs":
rels, ok := retrieved.(CommsEmailLogSlice)
if !ok {
return fmt.Errorf("commsEmail cannot load %T as %q", retrieved, name)
}
o.R.DestinationEmailLogs = rels
for _, rel := range rels {
if rel != nil {
rel.R.DestinationEmail = o
}
}
return nil
default:
return fmt.Errorf("commsEmail has no relationship %q", name)
}
}
type commsEmailPreloader struct{}
func buildCommsEmailPreloader() commsEmailPreloader {
return commsEmailPreloader{}
}
type commsEmailThenLoader[Q orm.Loadable] struct {
DestinationEmailLogs func(...bob.Mod[*dialect.SelectQuery]) orm.Loader[Q]
}
func buildCommsEmailThenLoader[Q orm.Loadable]() commsEmailThenLoader[Q] {
type DestinationEmailLogsLoadInterface interface {
LoadDestinationEmailLogs(context.Context, bob.Executor, ...bob.Mod[*dialect.SelectQuery]) error
}
return commsEmailThenLoader[Q]{
DestinationEmailLogs: thenLoadBuilder[Q](
"DestinationEmailLogs",
func(ctx context.Context, exec bob.Executor, retrieved DestinationEmailLogsLoadInterface, mods ...bob.Mod[*dialect.SelectQuery]) error {
return retrieved.LoadDestinationEmailLogs(ctx, exec, mods...)
},
),
}
}
// LoadDestinationEmailLogs loads the commsEmail's DestinationEmailLogs into the .R struct
func (o *CommsEmail) LoadDestinationEmailLogs(ctx context.Context, exec bob.Executor, mods ...bob.Mod[*dialect.SelectQuery]) error {
if o == nil {
return nil
}
// Reset the relationship
o.R.DestinationEmailLogs = nil
related, err := o.DestinationEmailLogs(mods...).All(ctx, exec)
if err != nil {
return err
}
for _, rel := range related {
rel.R.DestinationEmail = o
}
o.R.DestinationEmailLogs = related
return nil
}
// LoadDestinationEmailLogs loads the commsEmail's DestinationEmailLogs into the .R struct
func (os CommsEmailSlice) LoadDestinationEmailLogs(ctx context.Context, exec bob.Executor, mods ...bob.Mod[*dialect.SelectQuery]) error {
if len(os) == 0 {
return nil
}
commsEmailLogs, err := os.DestinationEmailLogs(mods...).All(ctx, exec)
if err != nil {
return err
}
for _, o := range os {
if o == nil {
continue
}
o.R.DestinationEmailLogs = nil
}
for _, o := range os {
if o == nil {
continue
}
for _, rel := range commsEmailLogs {
if !(o.Address == rel.Destination) {
continue
}
rel.R.DestinationEmail = o
o.R.DestinationEmailLogs = append(o.R.DestinationEmailLogs, rel)
}
}
return nil
}
// commsEmailC is where relationship counts are stored.
type commsEmailC struct {
DestinationEmailLogs *int64
}
// PreloadCount sets a count in the C struct by name
func (o *CommsEmail) PreloadCount(name string, count int64) error {
if o == nil {
return nil
}
switch name {
case "DestinationEmailLogs":
o.C.DestinationEmailLogs = &count
}
return nil
}
type commsEmailCountPreloader struct {
DestinationEmailLogs func(...bob.Mod[*dialect.SelectQuery]) psql.Preloader
}
func buildCommsEmailCountPreloader() commsEmailCountPreloader {
return commsEmailCountPreloader{
DestinationEmailLogs: func(mods ...bob.Mod[*dialect.SelectQuery]) psql.Preloader {
return countPreloader[*CommsEmail]("DestinationEmailLogs", func(parent string) bob.Expression {
// Build a correlated subquery: (SELECT COUNT(*) FROM related WHERE fk = parent.pk)
if parent == "" {
parent = CommsEmails.Alias()
}
subqueryMods := []bob.Mod[*dialect.SelectQuery]{
sm.Columns(psql.Raw("count(*)")),
sm.From(CommsEmailLogs.Name()),
sm.Where(psql.Quote(CommsEmailLogs.Alias(), "destination").EQ(psql.Quote(parent, "address"))),
}
subqueryMods = append(subqueryMods, mods...)
return psql.Group(psql.Select(subqueryMods...).Expression)
})
},
}
}
type commsEmailCountThenLoader[Q orm.Loadable] struct {
DestinationEmailLogs func(...bob.Mod[*dialect.SelectQuery]) orm.Loader[Q]
}
func buildCommsEmailCountThenLoader[Q orm.Loadable]() commsEmailCountThenLoader[Q] {
type DestinationEmailLogsCountInterface interface {
LoadCountDestinationEmailLogs(context.Context, bob.Executor, ...bob.Mod[*dialect.SelectQuery]) error
}
return commsEmailCountThenLoader[Q]{
DestinationEmailLogs: countThenLoadBuilder[Q](
"DestinationEmailLogs",
func(ctx context.Context, exec bob.Executor, retrieved DestinationEmailLogsCountInterface, mods ...bob.Mod[*dialect.SelectQuery]) error {
return retrieved.LoadCountDestinationEmailLogs(ctx, exec, mods...)
},
),
}
}
// LoadCountDestinationEmailLogs loads the count of DestinationEmailLogs into the C struct
func (o *CommsEmail) LoadCountDestinationEmailLogs(ctx context.Context, exec bob.Executor, mods ...bob.Mod[*dialect.SelectQuery]) error {
if o == nil {
return nil
}
count, err := o.DestinationEmailLogs(mods...).Count(ctx, exec)
if err != nil {
return err
}
o.C.DestinationEmailLogs = &count
return nil
}
// LoadCountDestinationEmailLogs loads the count of DestinationEmailLogs for a slice
func (os CommsEmailSlice) LoadCountDestinationEmailLogs(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.LoadCountDestinationEmailLogs(ctx, exec, mods...); err != nil {
return err
}
}
return nil
}
type commsEmailJoins[Q dialect.Joinable] struct {
typ string
DestinationEmailLogs modAs[Q, commsEmailLogColumns]
}
func (j commsEmailJoins[Q]) aliasedAs(alias string) commsEmailJoins[Q] {
return buildCommsEmailJoins[Q](buildCommsEmailColumns(alias), j.typ)
}
func buildCommsEmailJoins[Q dialect.Joinable](cols commsEmailColumns, typ string) commsEmailJoins[Q] {
return commsEmailJoins[Q]{
typ: typ,
DestinationEmailLogs: modAs[Q, commsEmailLogColumns]{
c: CommsEmailLogs.Columns,
f: func(to commsEmailLogColumns) bob.Mod[Q] {
mods := make(mods.QueryMods[Q], 0, 1)
{
mods = append(mods, dialect.Join[Q](typ, CommsEmailLogs.Name().As(to.Alias())).On(
to.Destination.EQ(cols.Address),
))
}
return mods
},
},
}
}

View file

@ -0,0 +1,762 @@
// Code generated by BobGen psql v0.42.1. DO NOT EDIT.
// This file is meant to be re-generated in place and/or deleted at any time.
package models
import (
"context"
"fmt"
"io"
"github.com/aarondl/opt/omit"
"github.com/stephenafamo/bob"
"github.com/stephenafamo/bob/dialect/psql"
"github.com/stephenafamo/bob/dialect/psql/dialect"
"github.com/stephenafamo/bob/dialect/psql/dm"
"github.com/stephenafamo/bob/dialect/psql/sm"
"github.com/stephenafamo/bob/dialect/psql/um"
"github.com/stephenafamo/bob/expr"
"github.com/stephenafamo/bob/mods"
"github.com/stephenafamo/bob/orm"
"github.com/stephenafamo/bob/types/pgtypes"
)
// CommsEmailContact is an object representing the database table.
type CommsEmailContact struct {
Address string `db:"address,pk" `
Confirmed bool `db:"confirmed" `
IsSubscribed bool `db:"is_subscribed" `
PublicID string `db:"public_id" `
R commsEmailContactR `db:"-" `
C commsEmailContactC `db:"-" `
}
// CommsEmailContactSlice is an alias for a slice of pointers to CommsEmailContact.
// This should almost always be used instead of []*CommsEmailContact.
type CommsEmailContactSlice []*CommsEmailContact
// CommsEmailContacts contains methods to work with the email_contact table
var CommsEmailContacts = psql.NewTablex[*CommsEmailContact, CommsEmailContactSlice, *CommsEmailContactSetter]("comms", "email_contact", buildCommsEmailContactColumns("comms.email_contact"))
// CommsEmailContactsQuery is a query on the email_contact table
type CommsEmailContactsQuery = *psql.ViewQuery[*CommsEmailContact, CommsEmailContactSlice]
// commsEmailContactR is where relationships are stored.
type commsEmailContactR struct {
DestinationEmailLogs CommsEmailLogSlice // comms.email_log.email_log_destination_fkey
}
func buildCommsEmailContactColumns(alias string) commsEmailContactColumns {
return commsEmailContactColumns{
ColumnsExpr: expr.NewColumnsExpr(
"address", "confirmed", "is_subscribed", "public_id",
).WithParent("comms.email_contact"),
tableAlias: alias,
Address: psql.Quote(alias, "address"),
Confirmed: psql.Quote(alias, "confirmed"),
IsSubscribed: psql.Quote(alias, "is_subscribed"),
PublicID: psql.Quote(alias, "public_id"),
}
}
type commsEmailContactColumns struct {
expr.ColumnsExpr
tableAlias string
Address psql.Expression
Confirmed psql.Expression
IsSubscribed psql.Expression
PublicID psql.Expression
}
func (c commsEmailContactColumns) Alias() string {
return c.tableAlias
}
func (commsEmailContactColumns) AliasedAs(alias string) commsEmailContactColumns {
return buildCommsEmailContactColumns(alias)
}
// CommsEmailContactSetter is used for insert/upsert/update operations
// All values are optional, and do not have to be set
// Generated columns are not included
type CommsEmailContactSetter struct {
Address omit.Val[string] `db:"address,pk" `
Confirmed omit.Val[bool] `db:"confirmed" `
IsSubscribed omit.Val[bool] `db:"is_subscribed" `
PublicID omit.Val[string] `db:"public_id" `
}
func (s CommsEmailContactSetter) SetColumns() []string {
vals := make([]string, 0, 4)
if s.Address.IsValue() {
vals = append(vals, "address")
}
if s.Confirmed.IsValue() {
vals = append(vals, "confirmed")
}
if s.IsSubscribed.IsValue() {
vals = append(vals, "is_subscribed")
}
if s.PublicID.IsValue() {
vals = append(vals, "public_id")
}
return vals
}
func (s CommsEmailContactSetter) Overwrite(t *CommsEmailContact) {
if s.Address.IsValue() {
t.Address = s.Address.MustGet()
}
if s.Confirmed.IsValue() {
t.Confirmed = s.Confirmed.MustGet()
}
if s.IsSubscribed.IsValue() {
t.IsSubscribed = s.IsSubscribed.MustGet()
}
if s.PublicID.IsValue() {
t.PublicID = s.PublicID.MustGet()
}
}
func (s *CommsEmailContactSetter) Apply(q *dialect.InsertQuery) {
q.AppendHooks(func(ctx context.Context, exec bob.Executor) (context.Context, error) {
return CommsEmailContacts.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, 4)
if s.Address.IsValue() {
vals[0] = psql.Arg(s.Address.MustGet())
} else {
vals[0] = psql.Raw("DEFAULT")
}
if s.Confirmed.IsValue() {
vals[1] = psql.Arg(s.Confirmed.MustGet())
} else {
vals[1] = psql.Raw("DEFAULT")
}
if s.IsSubscribed.IsValue() {
vals[2] = psql.Arg(s.IsSubscribed.MustGet())
} else {
vals[2] = psql.Raw("DEFAULT")
}
if s.PublicID.IsValue() {
vals[3] = psql.Arg(s.PublicID.MustGet())
} else {
vals[3] = psql.Raw("DEFAULT")
}
return bob.ExpressSlice(ctx, w, d, start, vals, "", ", ", "")
}))
}
func (s CommsEmailContactSetter) UpdateMod() bob.Mod[*dialect.UpdateQuery] {
return um.Set(s.Expressions()...)
}
func (s CommsEmailContactSetter) Expressions(prefix ...string) []bob.Expression {
exprs := make([]bob.Expression, 0, 4)
if s.Address.IsValue() {
exprs = append(exprs, expr.Join{Sep: " = ", Exprs: []bob.Expression{
psql.Quote(append(prefix, "address")...),
psql.Arg(s.Address),
}})
}
if s.Confirmed.IsValue() {
exprs = append(exprs, expr.Join{Sep: " = ", Exprs: []bob.Expression{
psql.Quote(append(prefix, "confirmed")...),
psql.Arg(s.Confirmed),
}})
}
if s.IsSubscribed.IsValue() {
exprs = append(exprs, expr.Join{Sep: " = ", Exprs: []bob.Expression{
psql.Quote(append(prefix, "is_subscribed")...),
psql.Arg(s.IsSubscribed),
}})
}
if s.PublicID.IsValue() {
exprs = append(exprs, expr.Join{Sep: " = ", Exprs: []bob.Expression{
psql.Quote(append(prefix, "public_id")...),
psql.Arg(s.PublicID),
}})
}
return exprs
}
// FindCommsEmailContact retrieves a single record by primary key
// If cols is empty Find will return all columns.
func FindCommsEmailContact(ctx context.Context, exec bob.Executor, AddressPK string, cols ...string) (*CommsEmailContact, error) {
if len(cols) == 0 {
return CommsEmailContacts.Query(
sm.Where(CommsEmailContacts.Columns.Address.EQ(psql.Arg(AddressPK))),
).One(ctx, exec)
}
return CommsEmailContacts.Query(
sm.Where(CommsEmailContacts.Columns.Address.EQ(psql.Arg(AddressPK))),
sm.Columns(CommsEmailContacts.Columns.Only(cols...)),
).One(ctx, exec)
}
// CommsEmailContactExists checks the presence of a single record by primary key
func CommsEmailContactExists(ctx context.Context, exec bob.Executor, AddressPK string) (bool, error) {
return CommsEmailContacts.Query(
sm.Where(CommsEmailContacts.Columns.Address.EQ(psql.Arg(AddressPK))),
).Exists(ctx, exec)
}
// AfterQueryHook is called after CommsEmailContact is retrieved from the database
func (o *CommsEmailContact) AfterQueryHook(ctx context.Context, exec bob.Executor, queryType bob.QueryType) error {
var err error
switch queryType {
case bob.QueryTypeSelect:
ctx, err = CommsEmailContacts.AfterSelectHooks.RunHooks(ctx, exec, CommsEmailContactSlice{o})
case bob.QueryTypeInsert:
ctx, err = CommsEmailContacts.AfterInsertHooks.RunHooks(ctx, exec, CommsEmailContactSlice{o})
case bob.QueryTypeUpdate:
ctx, err = CommsEmailContacts.AfterUpdateHooks.RunHooks(ctx, exec, CommsEmailContactSlice{o})
case bob.QueryTypeDelete:
ctx, err = CommsEmailContacts.AfterDeleteHooks.RunHooks(ctx, exec, CommsEmailContactSlice{o})
}
return err
}
// primaryKeyVals returns the primary key values of the CommsEmailContact
func (o *CommsEmailContact) primaryKeyVals() bob.Expression {
return psql.Arg(o.Address)
}
func (o *CommsEmailContact) pkEQ() dialect.Expression {
return psql.Quote("comms.email_contact", "address").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 CommsEmailContact
func (o *CommsEmailContact) Update(ctx context.Context, exec bob.Executor, s *CommsEmailContactSetter) error {
v, err := CommsEmailContacts.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 CommsEmailContact record with an executor
func (o *CommsEmailContact) Delete(ctx context.Context, exec bob.Executor) error {
_, err := CommsEmailContacts.Delete(dm.Where(o.pkEQ())).Exec(ctx, exec)
return err
}
// Reload refreshes the CommsEmailContact using the executor
func (o *CommsEmailContact) Reload(ctx context.Context, exec bob.Executor) error {
o2, err := CommsEmailContacts.Query(
sm.Where(CommsEmailContacts.Columns.Address.EQ(psql.Arg(o.Address))),
).One(ctx, exec)
if err != nil {
return err
}
o2.R = o.R
*o = *o2
return nil
}
// AfterQueryHook is called after CommsEmailContactSlice is retrieved from the database
func (o CommsEmailContactSlice) AfterQueryHook(ctx context.Context, exec bob.Executor, queryType bob.QueryType) error {
var err error
switch queryType {
case bob.QueryTypeSelect:
ctx, err = CommsEmailContacts.AfterSelectHooks.RunHooks(ctx, exec, o)
case bob.QueryTypeInsert:
ctx, err = CommsEmailContacts.AfterInsertHooks.RunHooks(ctx, exec, o)
case bob.QueryTypeUpdate:
ctx, err = CommsEmailContacts.AfterUpdateHooks.RunHooks(ctx, exec, o)
case bob.QueryTypeDelete:
ctx, err = CommsEmailContacts.AfterDeleteHooks.RunHooks(ctx, exec, o)
}
return err
}
func (o CommsEmailContactSlice) pkIN() dialect.Expression {
if len(o) == 0 {
return psql.Raw("NULL")
}
return psql.Quote("comms.email_contact", "address").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 CommsEmailContactSlice) copyMatchingRows(from ...*CommsEmailContact) {
for i, old := range o {
for _, new := range from {
if new.Address != old.Address {
continue
}
new.R = old.R
o[i] = new
break
}
}
}
// UpdateMod modifies an update query with "WHERE primary_key IN (o...)"
func (o CommsEmailContactSlice) 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 CommsEmailContacts.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 *CommsEmailContact:
o.copyMatchingRows(retrieved)
case []*CommsEmailContact:
o.copyMatchingRows(retrieved...)
case CommsEmailContactSlice:
o.copyMatchingRows(retrieved...)
default:
// If the retrieved value is not a CommsEmailContact or a slice of CommsEmailContact
// then run the AfterUpdateHooks on the slice
_, err = CommsEmailContacts.AfterUpdateHooks.RunHooks(ctx, exec, o)
}
return err
}))
q.AppendWhere(o.pkIN())
})
}
// DeleteMod modifies an delete query with "WHERE primary_key IN (o...)"
func (o CommsEmailContactSlice) 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 CommsEmailContacts.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 *CommsEmailContact:
o.copyMatchingRows(retrieved)
case []*CommsEmailContact:
o.copyMatchingRows(retrieved...)
case CommsEmailContactSlice:
o.copyMatchingRows(retrieved...)
default:
// If the retrieved value is not a CommsEmailContact or a slice of CommsEmailContact
// then run the AfterDeleteHooks on the slice
_, err = CommsEmailContacts.AfterDeleteHooks.RunHooks(ctx, exec, o)
}
return err
}))
q.AppendWhere(o.pkIN())
})
}
func (o CommsEmailContactSlice) UpdateAll(ctx context.Context, exec bob.Executor, vals CommsEmailContactSetter) error {
if len(o) == 0 {
return nil
}
_, err := CommsEmailContacts.Update(vals.UpdateMod(), o.UpdateMod()).All(ctx, exec)
return err
}
func (o CommsEmailContactSlice) DeleteAll(ctx context.Context, exec bob.Executor) error {
if len(o) == 0 {
return nil
}
_, err := CommsEmailContacts.Delete(o.DeleteMod()).Exec(ctx, exec)
return err
}
func (o CommsEmailContactSlice) ReloadAll(ctx context.Context, exec bob.Executor) error {
if len(o) == 0 {
return nil
}
o2, err := CommsEmailContacts.Query(sm.Where(o.pkIN())).All(ctx, exec)
if err != nil {
return err
}
o.copyMatchingRows(o2...)
return nil
}
// DestinationEmailLogs starts a query for related objects on comms.email_log
func (o *CommsEmailContact) DestinationEmailLogs(mods ...bob.Mod[*dialect.SelectQuery]) CommsEmailLogsQuery {
return CommsEmailLogs.Query(append(mods,
sm.Where(CommsEmailLogs.Columns.Destination.EQ(psql.Arg(o.Address))),
)...)
}
func (os CommsEmailContactSlice) DestinationEmailLogs(mods ...bob.Mod[*dialect.SelectQuery]) CommsEmailLogsQuery {
pkAddress := make(pgtypes.Array[string], 0, len(os))
for _, o := range os {
if o == nil {
continue
}
pkAddress = append(pkAddress, o.Address)
}
PKArgExpr := psql.Select(sm.Columns(
psql.F("unnest", psql.Cast(psql.Arg(pkAddress), "text[]")),
))
return CommsEmailLogs.Query(append(mods,
sm.Where(psql.Group(CommsEmailLogs.Columns.Destination).OP("IN", PKArgExpr)),
)...)
}
func insertCommsEmailContactDestinationEmailLogs0(ctx context.Context, exec bob.Executor, commsEmailLogs1 []*CommsEmailLogSetter, commsEmailContact0 *CommsEmailContact) (CommsEmailLogSlice, error) {
for i := range commsEmailLogs1 {
commsEmailLogs1[i].Destination = omit.From(commsEmailContact0.Address)
}
ret, err := CommsEmailLogs.Insert(bob.ToMods(commsEmailLogs1...)).All(ctx, exec)
if err != nil {
return ret, fmt.Errorf("insertCommsEmailContactDestinationEmailLogs0: %w", err)
}
return ret, nil
}
func attachCommsEmailContactDestinationEmailLogs0(ctx context.Context, exec bob.Executor, count int, commsEmailLogs1 CommsEmailLogSlice, commsEmailContact0 *CommsEmailContact) (CommsEmailLogSlice, error) {
setter := &CommsEmailLogSetter{
Destination: omit.From(commsEmailContact0.Address),
}
err := commsEmailLogs1.UpdateAll(ctx, exec, *setter)
if err != nil {
return nil, fmt.Errorf("attachCommsEmailContactDestinationEmailLogs0: %w", err)
}
return commsEmailLogs1, nil
}
func (commsEmailContact0 *CommsEmailContact) InsertDestinationEmailLogs(ctx context.Context, exec bob.Executor, related ...*CommsEmailLogSetter) error {
if len(related) == 0 {
return nil
}
var err error
commsEmailLogs1, err := insertCommsEmailContactDestinationEmailLogs0(ctx, exec, related, commsEmailContact0)
if err != nil {
return err
}
commsEmailContact0.R.DestinationEmailLogs = append(commsEmailContact0.R.DestinationEmailLogs, commsEmailLogs1...)
for _, rel := range commsEmailLogs1 {
rel.R.DestinationEmailContact = commsEmailContact0
}
return nil
}
func (commsEmailContact0 *CommsEmailContact) AttachDestinationEmailLogs(ctx context.Context, exec bob.Executor, related ...*CommsEmailLog) error {
if len(related) == 0 {
return nil
}
var err error
commsEmailLogs1 := CommsEmailLogSlice(related)
_, err = attachCommsEmailContactDestinationEmailLogs0(ctx, exec, len(related), commsEmailLogs1, commsEmailContact0)
if err != nil {
return err
}
commsEmailContact0.R.DestinationEmailLogs = append(commsEmailContact0.R.DestinationEmailLogs, commsEmailLogs1...)
for _, rel := range related {
rel.R.DestinationEmailContact = commsEmailContact0
}
return nil
}
type commsEmailContactWhere[Q psql.Filterable] struct {
Address psql.WhereMod[Q, string]
Confirmed psql.WhereMod[Q, bool]
IsSubscribed psql.WhereMod[Q, bool]
PublicID psql.WhereMod[Q, string]
}
func (commsEmailContactWhere[Q]) AliasedAs(alias string) commsEmailContactWhere[Q] {
return buildCommsEmailContactWhere[Q](buildCommsEmailContactColumns(alias))
}
func buildCommsEmailContactWhere[Q psql.Filterable](cols commsEmailContactColumns) commsEmailContactWhere[Q] {
return commsEmailContactWhere[Q]{
Address: psql.Where[Q, string](cols.Address),
Confirmed: psql.Where[Q, bool](cols.Confirmed),
IsSubscribed: psql.Where[Q, bool](cols.IsSubscribed),
PublicID: psql.Where[Q, string](cols.PublicID),
}
}
func (o *CommsEmailContact) Preload(name string, retrieved any) error {
if o == nil {
return nil
}
switch name {
case "DestinationEmailLogs":
rels, ok := retrieved.(CommsEmailLogSlice)
if !ok {
return fmt.Errorf("commsEmailContact cannot load %T as %q", retrieved, name)
}
o.R.DestinationEmailLogs = rels
for _, rel := range rels {
if rel != nil {
rel.R.DestinationEmailContact = o
}
}
return nil
default:
return fmt.Errorf("commsEmailContact has no relationship %q", name)
}
}
type commsEmailContactPreloader struct{}
func buildCommsEmailContactPreloader() commsEmailContactPreloader {
return commsEmailContactPreloader{}
}
type commsEmailContactThenLoader[Q orm.Loadable] struct {
DestinationEmailLogs func(...bob.Mod[*dialect.SelectQuery]) orm.Loader[Q]
}
func buildCommsEmailContactThenLoader[Q orm.Loadable]() commsEmailContactThenLoader[Q] {
type DestinationEmailLogsLoadInterface interface {
LoadDestinationEmailLogs(context.Context, bob.Executor, ...bob.Mod[*dialect.SelectQuery]) error
}
return commsEmailContactThenLoader[Q]{
DestinationEmailLogs: thenLoadBuilder[Q](
"DestinationEmailLogs",
func(ctx context.Context, exec bob.Executor, retrieved DestinationEmailLogsLoadInterface, mods ...bob.Mod[*dialect.SelectQuery]) error {
return retrieved.LoadDestinationEmailLogs(ctx, exec, mods...)
},
),
}
}
// LoadDestinationEmailLogs loads the commsEmailContact's DestinationEmailLogs into the .R struct
func (o *CommsEmailContact) LoadDestinationEmailLogs(ctx context.Context, exec bob.Executor, mods ...bob.Mod[*dialect.SelectQuery]) error {
if o == nil {
return nil
}
// Reset the relationship
o.R.DestinationEmailLogs = nil
related, err := o.DestinationEmailLogs(mods...).All(ctx, exec)
if err != nil {
return err
}
for _, rel := range related {
rel.R.DestinationEmailContact = o
}
o.R.DestinationEmailLogs = related
return nil
}
// LoadDestinationEmailLogs loads the commsEmailContact's DestinationEmailLogs into the .R struct
func (os CommsEmailContactSlice) LoadDestinationEmailLogs(ctx context.Context, exec bob.Executor, mods ...bob.Mod[*dialect.SelectQuery]) error {
if len(os) == 0 {
return nil
}
commsEmailLogs, err := os.DestinationEmailLogs(mods...).All(ctx, exec)
if err != nil {
return err
}
for _, o := range os {
if o == nil {
continue
}
o.R.DestinationEmailLogs = nil
}
for _, o := range os {
if o == nil {
continue
}
for _, rel := range commsEmailLogs {
if !(o.Address == rel.Destination) {
continue
}
rel.R.DestinationEmailContact = o
o.R.DestinationEmailLogs = append(o.R.DestinationEmailLogs, rel)
}
}
return nil
}
// commsEmailContactC is where relationship counts are stored.
type commsEmailContactC struct {
DestinationEmailLogs *int64
}
// PreloadCount sets a count in the C struct by name
func (o *CommsEmailContact) PreloadCount(name string, count int64) error {
if o == nil {
return nil
}
switch name {
case "DestinationEmailLogs":
o.C.DestinationEmailLogs = &count
}
return nil
}
type commsEmailContactCountPreloader struct {
DestinationEmailLogs func(...bob.Mod[*dialect.SelectQuery]) psql.Preloader
}
func buildCommsEmailContactCountPreloader() commsEmailContactCountPreloader {
return commsEmailContactCountPreloader{
DestinationEmailLogs: func(mods ...bob.Mod[*dialect.SelectQuery]) psql.Preloader {
return countPreloader[*CommsEmailContact]("DestinationEmailLogs", func(parent string) bob.Expression {
// Build a correlated subquery: (SELECT COUNT(*) FROM related WHERE fk = parent.pk)
if parent == "" {
parent = CommsEmailContacts.Alias()
}
subqueryMods := []bob.Mod[*dialect.SelectQuery]{
sm.Columns(psql.Raw("count(*)")),
sm.From(CommsEmailLogs.Name()),
sm.Where(psql.Quote(CommsEmailLogs.Alias(), "destination").EQ(psql.Quote(parent, "address"))),
}
subqueryMods = append(subqueryMods, mods...)
return psql.Group(psql.Select(subqueryMods...).Expression)
})
},
}
}
type commsEmailContactCountThenLoader[Q orm.Loadable] struct {
DestinationEmailLogs func(...bob.Mod[*dialect.SelectQuery]) orm.Loader[Q]
}
func buildCommsEmailContactCountThenLoader[Q orm.Loadable]() commsEmailContactCountThenLoader[Q] {
type DestinationEmailLogsCountInterface interface {
LoadCountDestinationEmailLogs(context.Context, bob.Executor, ...bob.Mod[*dialect.SelectQuery]) error
}
return commsEmailContactCountThenLoader[Q]{
DestinationEmailLogs: countThenLoadBuilder[Q](
"DestinationEmailLogs",
func(ctx context.Context, exec bob.Executor, retrieved DestinationEmailLogsCountInterface, mods ...bob.Mod[*dialect.SelectQuery]) error {
return retrieved.LoadCountDestinationEmailLogs(ctx, exec, mods...)
},
),
}
}
// LoadCountDestinationEmailLogs loads the count of DestinationEmailLogs into the C struct
func (o *CommsEmailContact) LoadCountDestinationEmailLogs(ctx context.Context, exec bob.Executor, mods ...bob.Mod[*dialect.SelectQuery]) error {
if o == nil {
return nil
}
count, err := o.DestinationEmailLogs(mods...).Count(ctx, exec)
if err != nil {
return err
}
o.C.DestinationEmailLogs = &count
return nil
}
// LoadCountDestinationEmailLogs loads the count of DestinationEmailLogs for a slice
func (os CommsEmailContactSlice) LoadCountDestinationEmailLogs(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.LoadCountDestinationEmailLogs(ctx, exec, mods...); err != nil {
return err
}
}
return nil
}
type commsEmailContactJoins[Q dialect.Joinable] struct {
typ string
DestinationEmailLogs modAs[Q, commsEmailLogColumns]
}
func (j commsEmailContactJoins[Q]) aliasedAs(alias string) commsEmailContactJoins[Q] {
return buildCommsEmailContactJoins[Q](buildCommsEmailContactColumns(alias), j.typ)
}
func buildCommsEmailContactJoins[Q dialect.Joinable](cols commsEmailContactColumns, typ string) commsEmailContactJoins[Q] {
return commsEmailContactJoins[Q]{
typ: typ,
DestinationEmailLogs: modAs[Q, commsEmailLogColumns]{
c: CommsEmailLogs.Columns,
f: func(to commsEmailLogColumns) bob.Mod[Q] {
mods := make(mods.QueryMods[Q], 0, 1)
{
mods = append(mods, dialect.Join[Q](typ, CommsEmailLogs.Name().As(to.Alias())).On(
to.Destination.EQ(cols.Address),
))
}
return mods
},
},
}
}

View file

@ -10,7 +10,9 @@ import (
"time"
enums "github.com/Gleipnir-Technology/nidus-sync/db/enums"
"github.com/aarondl/opt/null"
"github.com/aarondl/opt/omit"
"github.com/aarondl/opt/omitnull"
"github.com/stephenafamo/bob"
"github.com/stephenafamo/bob/dialect/psql"
"github.com/stephenafamo/bob/dialect/psql/dialect"
@ -25,10 +27,17 @@ import (
// CommsEmailLog is an object representing the database table.
type CommsEmailLog struct {
Created time.Time `db:"created" `
Destination string `db:"destination,pk" `
Source string `db:"source,pk" `
Type enums.CommsMessagetypeemail `db:"type,pk" `
ID int32 `db:"id,pk" `
Created time.Time `db:"created" `
DeliveryStatus string `db:"delivery_status" `
Destination string `db:"destination" `
PublicID string `db:"public_id" `
SentAt null.Val[time.Time] `db:"sent_at" `
Source string `db:"source" `
Subject string `db:"subject" `
TemplateID null.Val[int32] `db:"template_id" `
TemplateData pgtypes.HStore `db:"template_data" `
Type enums.CommsMessagetypeemail `db:"type" `
R commsEmailLogR `db:"-" `
}
@ -45,30 +54,44 @@ type CommsEmailLogsQuery = *psql.ViewQuery[*CommsEmailLog, CommsEmailLogSlice]
// commsEmailLogR is where relationships are stored.
type commsEmailLogR struct {
DestinationEmail *CommsEmail // comms.email_log.email_log_destination_fkey
SourcePhone *CommsPhone // comms.email_log.email_log_source_fkey
DestinationEmailContact *CommsEmailContact // comms.email_log.email_log_destination_fkey
TemplateEmailTemplate *CommsEmailTemplate // comms.email_log.email_log_template_id_fkey
}
func buildCommsEmailLogColumns(alias string) commsEmailLogColumns {
return commsEmailLogColumns{
ColumnsExpr: expr.NewColumnsExpr(
"created", "destination", "source", "type",
"id", "created", "delivery_status", "destination", "public_id", "sent_at", "source", "subject", "template_id", "template_data", "type",
).WithParent("comms.email_log"),
tableAlias: alias,
Created: psql.Quote(alias, "created"),
Destination: psql.Quote(alias, "destination"),
Source: psql.Quote(alias, "source"),
Type: psql.Quote(alias, "type"),
tableAlias: alias,
ID: psql.Quote(alias, "id"),
Created: psql.Quote(alias, "created"),
DeliveryStatus: psql.Quote(alias, "delivery_status"),
Destination: psql.Quote(alias, "destination"),
PublicID: psql.Quote(alias, "public_id"),
SentAt: psql.Quote(alias, "sent_at"),
Source: psql.Quote(alias, "source"),
Subject: psql.Quote(alias, "subject"),
TemplateID: psql.Quote(alias, "template_id"),
TemplateData: psql.Quote(alias, "template_data"),
Type: psql.Quote(alias, "type"),
}
}
type commsEmailLogColumns struct {
expr.ColumnsExpr
tableAlias string
Created psql.Expression
Destination psql.Expression
Source psql.Expression
Type psql.Expression
tableAlias string
ID psql.Expression
Created psql.Expression
DeliveryStatus psql.Expression
Destination psql.Expression
PublicID psql.Expression
SentAt psql.Expression
Source psql.Expression
Subject psql.Expression
TemplateID psql.Expression
TemplateData psql.Expression
Type psql.Expression
}
func (c commsEmailLogColumns) Alias() string {
@ -83,23 +106,51 @@ func (commsEmailLogColumns) AliasedAs(alias string) commsEmailLogColumns {
// All values are optional, and do not have to be set
// Generated columns are not included
type CommsEmailLogSetter struct {
Created omit.Val[time.Time] `db:"created" `
Destination omit.Val[string] `db:"destination,pk" `
Source omit.Val[string] `db:"source,pk" `
Type omit.Val[enums.CommsMessagetypeemail] `db:"type,pk" `
ID omit.Val[int32] `db:"id,pk" `
Created omit.Val[time.Time] `db:"created" `
DeliveryStatus omit.Val[string] `db:"delivery_status" `
Destination omit.Val[string] `db:"destination" `
PublicID omit.Val[string] `db:"public_id" `
SentAt omitnull.Val[time.Time] `db:"sent_at" `
Source omit.Val[string] `db:"source" `
Subject omit.Val[string] `db:"subject" `
TemplateID omitnull.Val[int32] `db:"template_id" `
TemplateData omit.Val[pgtypes.HStore] `db:"template_data" `
Type omit.Val[enums.CommsMessagetypeemail] `db:"type" `
}
func (s CommsEmailLogSetter) SetColumns() []string {
vals := make([]string, 0, 4)
vals := make([]string, 0, 11)
if s.ID.IsValue() {
vals = append(vals, "id")
}
if s.Created.IsValue() {
vals = append(vals, "created")
}
if s.DeliveryStatus.IsValue() {
vals = append(vals, "delivery_status")
}
if s.Destination.IsValue() {
vals = append(vals, "destination")
}
if s.PublicID.IsValue() {
vals = append(vals, "public_id")
}
if !s.SentAt.IsUnset() {
vals = append(vals, "sent_at")
}
if s.Source.IsValue() {
vals = append(vals, "source")
}
if s.Subject.IsValue() {
vals = append(vals, "subject")
}
if !s.TemplateID.IsUnset() {
vals = append(vals, "template_id")
}
if s.TemplateData.IsValue() {
vals = append(vals, "template_data")
}
if s.Type.IsValue() {
vals = append(vals, "type")
}
@ -107,15 +158,36 @@ func (s CommsEmailLogSetter) SetColumns() []string {
}
func (s CommsEmailLogSetter) Overwrite(t *CommsEmailLog) {
if s.ID.IsValue() {
t.ID = s.ID.MustGet()
}
if s.Created.IsValue() {
t.Created = s.Created.MustGet()
}
if s.DeliveryStatus.IsValue() {
t.DeliveryStatus = s.DeliveryStatus.MustGet()
}
if s.Destination.IsValue() {
t.Destination = s.Destination.MustGet()
}
if s.PublicID.IsValue() {
t.PublicID = s.PublicID.MustGet()
}
if !s.SentAt.IsUnset() {
t.SentAt = s.SentAt.MustGetNull()
}
if s.Source.IsValue() {
t.Source = s.Source.MustGet()
}
if s.Subject.IsValue() {
t.Subject = s.Subject.MustGet()
}
if !s.TemplateID.IsUnset() {
t.TemplateID = s.TemplateID.MustGetNull()
}
if s.TemplateData.IsValue() {
t.TemplateData = s.TemplateData.MustGet()
}
if s.Type.IsValue() {
t.Type = s.Type.MustGet()
}
@ -127,31 +199,73 @@ func (s *CommsEmailLogSetter) Apply(q *dialect.InsertQuery) {
})
q.AppendValues(bob.ExpressionFunc(func(ctx context.Context, w io.StringWriter, d bob.Dialect, start int) ([]any, error) {
vals := make([]bob.Expression, 4)
if s.Created.IsValue() {
vals[0] = psql.Arg(s.Created.MustGet())
vals := make([]bob.Expression, 11)
if s.ID.IsValue() {
vals[0] = psql.Arg(s.ID.MustGet())
} else {
vals[0] = psql.Raw("DEFAULT")
}
if s.Destination.IsValue() {
vals[1] = psql.Arg(s.Destination.MustGet())
if s.Created.IsValue() {
vals[1] = psql.Arg(s.Created.MustGet())
} else {
vals[1] = psql.Raw("DEFAULT")
}
if s.Source.IsValue() {
vals[2] = psql.Arg(s.Source.MustGet())
if s.DeliveryStatus.IsValue() {
vals[2] = psql.Arg(s.DeliveryStatus.MustGet())
} else {
vals[2] = psql.Raw("DEFAULT")
}
if s.Type.IsValue() {
vals[3] = psql.Arg(s.Type.MustGet())
if s.Destination.IsValue() {
vals[3] = psql.Arg(s.Destination.MustGet())
} else {
vals[3] = psql.Raw("DEFAULT")
}
if s.PublicID.IsValue() {
vals[4] = psql.Arg(s.PublicID.MustGet())
} else {
vals[4] = psql.Raw("DEFAULT")
}
if !s.SentAt.IsUnset() {
vals[5] = psql.Arg(s.SentAt.MustGetNull())
} else {
vals[5] = psql.Raw("DEFAULT")
}
if s.Source.IsValue() {
vals[6] = psql.Arg(s.Source.MustGet())
} else {
vals[6] = psql.Raw("DEFAULT")
}
if s.Subject.IsValue() {
vals[7] = psql.Arg(s.Subject.MustGet())
} else {
vals[7] = psql.Raw("DEFAULT")
}
if !s.TemplateID.IsUnset() {
vals[8] = psql.Arg(s.TemplateID.MustGetNull())
} else {
vals[8] = psql.Raw("DEFAULT")
}
if s.TemplateData.IsValue() {
vals[9] = psql.Arg(s.TemplateData.MustGet())
} else {
vals[9] = psql.Raw("DEFAULT")
}
if s.Type.IsValue() {
vals[10] = psql.Arg(s.Type.MustGet())
} else {
vals[10] = psql.Raw("DEFAULT")
}
return bob.ExpressSlice(ctx, w, d, start, vals, "", ", ", "")
}))
}
@ -161,7 +275,14 @@ func (s CommsEmailLogSetter) UpdateMod() bob.Mod[*dialect.UpdateQuery] {
}
func (s CommsEmailLogSetter) Expressions(prefix ...string) []bob.Expression {
exprs := make([]bob.Expression, 0, 4)
exprs := make([]bob.Expression, 0, 11)
if s.ID.IsValue() {
exprs = append(exprs, expr.Join{Sep: " = ", Exprs: []bob.Expression{
psql.Quote(append(prefix, "id")...),
psql.Arg(s.ID),
}})
}
if s.Created.IsValue() {
exprs = append(exprs, expr.Join{Sep: " = ", Exprs: []bob.Expression{
@ -170,6 +291,13 @@ func (s CommsEmailLogSetter) Expressions(prefix ...string) []bob.Expression {
}})
}
if s.DeliveryStatus.IsValue() {
exprs = append(exprs, expr.Join{Sep: " = ", Exprs: []bob.Expression{
psql.Quote(append(prefix, "delivery_status")...),
psql.Arg(s.DeliveryStatus),
}})
}
if s.Destination.IsValue() {
exprs = append(exprs, expr.Join{Sep: " = ", Exprs: []bob.Expression{
psql.Quote(append(prefix, "destination")...),
@ -177,6 +305,20 @@ func (s CommsEmailLogSetter) Expressions(prefix ...string) []bob.Expression {
}})
}
if s.PublicID.IsValue() {
exprs = append(exprs, expr.Join{Sep: " = ", Exprs: []bob.Expression{
psql.Quote(append(prefix, "public_id")...),
psql.Arg(s.PublicID),
}})
}
if !s.SentAt.IsUnset() {
exprs = append(exprs, expr.Join{Sep: " = ", Exprs: []bob.Expression{
psql.Quote(append(prefix, "sent_at")...),
psql.Arg(s.SentAt),
}})
}
if s.Source.IsValue() {
exprs = append(exprs, expr.Join{Sep: " = ", Exprs: []bob.Expression{
psql.Quote(append(prefix, "source")...),
@ -184,6 +326,27 @@ func (s CommsEmailLogSetter) Expressions(prefix ...string) []bob.Expression {
}})
}
if s.Subject.IsValue() {
exprs = append(exprs, expr.Join{Sep: " = ", Exprs: []bob.Expression{
psql.Quote(append(prefix, "subject")...),
psql.Arg(s.Subject),
}})
}
if !s.TemplateID.IsUnset() {
exprs = append(exprs, expr.Join{Sep: " = ", Exprs: []bob.Expression{
psql.Quote(append(prefix, "template_id")...),
psql.Arg(s.TemplateID),
}})
}
if s.TemplateData.IsValue() {
exprs = append(exprs, expr.Join{Sep: " = ", Exprs: []bob.Expression{
psql.Quote(append(prefix, "template_data")...),
psql.Arg(s.TemplateData),
}})
}
if s.Type.IsValue() {
exprs = append(exprs, expr.Join{Sep: " = ", Exprs: []bob.Expression{
psql.Quote(append(prefix, "type")...),
@ -196,29 +359,23 @@ func (s CommsEmailLogSetter) Expressions(prefix ...string) []bob.Expression {
// FindCommsEmailLog retrieves a single record by primary key
// If cols is empty Find will return all columns.
func FindCommsEmailLog(ctx context.Context, exec bob.Executor, DestinationPK string, SourcePK string, TypePK enums.CommsMessagetypeemail, cols ...string) (*CommsEmailLog, error) {
func FindCommsEmailLog(ctx context.Context, exec bob.Executor, IDPK int32, cols ...string) (*CommsEmailLog, error) {
if len(cols) == 0 {
return CommsEmailLogs.Query(
sm.Where(CommsEmailLogs.Columns.Destination.EQ(psql.Arg(DestinationPK))),
sm.Where(CommsEmailLogs.Columns.Source.EQ(psql.Arg(SourcePK))),
sm.Where(CommsEmailLogs.Columns.Type.EQ(psql.Arg(TypePK))),
sm.Where(CommsEmailLogs.Columns.ID.EQ(psql.Arg(IDPK))),
).One(ctx, exec)
}
return CommsEmailLogs.Query(
sm.Where(CommsEmailLogs.Columns.Destination.EQ(psql.Arg(DestinationPK))),
sm.Where(CommsEmailLogs.Columns.Source.EQ(psql.Arg(SourcePK))),
sm.Where(CommsEmailLogs.Columns.Type.EQ(psql.Arg(TypePK))),
sm.Where(CommsEmailLogs.Columns.ID.EQ(psql.Arg(IDPK))),
sm.Columns(CommsEmailLogs.Columns.Only(cols...)),
).One(ctx, exec)
}
// CommsEmailLogExists checks the presence of a single record by primary key
func CommsEmailLogExists(ctx context.Context, exec bob.Executor, DestinationPK string, SourcePK string, TypePK enums.CommsMessagetypeemail) (bool, error) {
func CommsEmailLogExists(ctx context.Context, exec bob.Executor, IDPK int32) (bool, error) {
return CommsEmailLogs.Query(
sm.Where(CommsEmailLogs.Columns.Destination.EQ(psql.Arg(DestinationPK))),
sm.Where(CommsEmailLogs.Columns.Source.EQ(psql.Arg(SourcePK))),
sm.Where(CommsEmailLogs.Columns.Type.EQ(psql.Arg(TypePK))),
sm.Where(CommsEmailLogs.Columns.ID.EQ(psql.Arg(IDPK))),
).Exists(ctx, exec)
}
@ -242,15 +399,11 @@ func (o *CommsEmailLog) AfterQueryHook(ctx context.Context, exec bob.Executor, q
// primaryKeyVals returns the primary key values of the CommsEmailLog
func (o *CommsEmailLog) primaryKeyVals() bob.Expression {
return psql.ArgGroup(
o.Destination,
o.Source,
o.Type,
)
return psql.Arg(o.ID)
}
func (o *CommsEmailLog) pkEQ() dialect.Expression {
return psql.Group(psql.Quote("comms.email_log", "destination"), psql.Quote("comms.email_log", "source"), psql.Quote("comms.email_log", "type")).EQ(bob.ExpressionFunc(func(ctx context.Context, w io.StringWriter, d bob.Dialect, start int) ([]any, error) {
return psql.Quote("comms.email_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)
}))
}
@ -277,9 +430,7 @@ func (o *CommsEmailLog) Delete(ctx context.Context, exec bob.Executor) error {
// Reload refreshes the CommsEmailLog using the executor
func (o *CommsEmailLog) Reload(ctx context.Context, exec bob.Executor) error {
o2, err := CommsEmailLogs.Query(
sm.Where(CommsEmailLogs.Columns.Destination.EQ(psql.Arg(o.Destination))),
sm.Where(CommsEmailLogs.Columns.Source.EQ(psql.Arg(o.Source))),
sm.Where(CommsEmailLogs.Columns.Type.EQ(psql.Arg(o.Type))),
sm.Where(CommsEmailLogs.Columns.ID.EQ(psql.Arg(o.ID))),
).One(ctx, exec)
if err != nil {
return err
@ -313,7 +464,7 @@ func (o CommsEmailLogSlice) pkIN() dialect.Expression {
return psql.Raw("NULL")
}
return psql.Group(psql.Quote("comms.email_log", "destination"), psql.Quote("comms.email_log", "source"), psql.Quote("comms.email_log", "type")).In(bob.ExpressionFunc(func(ctx context.Context, w io.StringWriter, d bob.Dialect, start int) ([]any, error) {
return psql.Quote("comms.email_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()
@ -328,13 +479,7 @@ func (o CommsEmailLogSlice) pkIN() dialect.Expression {
func (o CommsEmailLogSlice) copyMatchingRows(from ...*CommsEmailLog) {
for i, old := range o {
for _, new := range from {
if new.Destination != old.Destination {
continue
}
if new.Source != old.Source {
continue
}
if new.Type != old.Type {
if new.ID != old.ID {
continue
}
new.R = old.R
@ -435,14 +580,14 @@ func (o CommsEmailLogSlice) ReloadAll(ctx context.Context, exec bob.Executor) er
return nil
}
// DestinationEmail starts a query for related objects on comms.email
func (o *CommsEmailLog) DestinationEmail(mods ...bob.Mod[*dialect.SelectQuery]) CommsEmailsQuery {
return CommsEmails.Query(append(mods,
sm.Where(CommsEmails.Columns.Address.EQ(psql.Arg(o.Destination))),
// DestinationEmailContact starts a query for related objects on comms.email_contact
func (o *CommsEmailLog) DestinationEmailContact(mods ...bob.Mod[*dialect.SelectQuery]) CommsEmailContactsQuery {
return CommsEmailContacts.Query(append(mods,
sm.Where(CommsEmailContacts.Columns.Address.EQ(psql.Arg(o.Destination))),
)...)
}
func (os CommsEmailLogSlice) DestinationEmail(mods ...bob.Mod[*dialect.SelectQuery]) CommsEmailsQuery {
func (os CommsEmailLogSlice) DestinationEmailContact(mods ...bob.Mod[*dialect.SelectQuery]) CommsEmailContactsQuery {
pkDestination := make(pgtypes.Array[string], 0, len(os))
for _, o := range os {
if o == nil {
@ -454,136 +599,143 @@ func (os CommsEmailLogSlice) DestinationEmail(mods ...bob.Mod[*dialect.SelectQue
psql.F("unnest", psql.Cast(psql.Arg(pkDestination), "text[]")),
))
return CommsEmails.Query(append(mods,
sm.Where(psql.Group(CommsEmails.Columns.Address).OP("IN", PKArgExpr)),
return CommsEmailContacts.Query(append(mods,
sm.Where(psql.Group(CommsEmailContacts.Columns.Address).OP("IN", PKArgExpr)),
)...)
}
// SourcePhone starts a query for related objects on comms.phone
func (o *CommsEmailLog) SourcePhone(mods ...bob.Mod[*dialect.SelectQuery]) CommsPhonesQuery {
return CommsPhones.Query(append(mods,
sm.Where(CommsPhones.Columns.E164.EQ(psql.Arg(o.Source))),
// TemplateEmailTemplate starts a query for related objects on comms.email_template
func (o *CommsEmailLog) TemplateEmailTemplate(mods ...bob.Mod[*dialect.SelectQuery]) CommsEmailTemplatesQuery {
return CommsEmailTemplates.Query(append(mods,
sm.Where(CommsEmailTemplates.Columns.ID.EQ(psql.Arg(o.TemplateID))),
)...)
}
func (os CommsEmailLogSlice) SourcePhone(mods ...bob.Mod[*dialect.SelectQuery]) CommsPhonesQuery {
pkSource := make(pgtypes.Array[string], 0, len(os))
func (os CommsEmailLogSlice) TemplateEmailTemplate(mods ...bob.Mod[*dialect.SelectQuery]) CommsEmailTemplatesQuery {
pkTemplateID := make(pgtypes.Array[null.Val[int32]], 0, len(os))
for _, o := range os {
if o == nil {
continue
}
pkSource = append(pkSource, o.Source)
pkTemplateID = append(pkTemplateID, o.TemplateID)
}
PKArgExpr := psql.Select(sm.Columns(
psql.F("unnest", psql.Cast(psql.Arg(pkSource), "text[]")),
psql.F("unnest", psql.Cast(psql.Arg(pkTemplateID), "integer[]")),
))
return CommsPhones.Query(append(mods,
sm.Where(psql.Group(CommsPhones.Columns.E164).OP("IN", PKArgExpr)),
return CommsEmailTemplates.Query(append(mods,
sm.Where(psql.Group(CommsEmailTemplates.Columns.ID).OP("IN", PKArgExpr)),
)...)
}
func attachCommsEmailLogDestinationEmail0(ctx context.Context, exec bob.Executor, count int, commsEmailLog0 *CommsEmailLog, commsEmail1 *CommsEmail) (*CommsEmailLog, error) {
func attachCommsEmailLogDestinationEmailContact0(ctx context.Context, exec bob.Executor, count int, commsEmailLog0 *CommsEmailLog, commsEmailContact1 *CommsEmailContact) (*CommsEmailLog, error) {
setter := &CommsEmailLogSetter{
Destination: omit.From(commsEmail1.Address),
Destination: omit.From(commsEmailContact1.Address),
}
err := commsEmailLog0.Update(ctx, exec, setter)
if err != nil {
return nil, fmt.Errorf("attachCommsEmailLogDestinationEmail0: %w", err)
return nil, fmt.Errorf("attachCommsEmailLogDestinationEmailContact0: %w", err)
}
return commsEmailLog0, nil
}
func (commsEmailLog0 *CommsEmailLog) InsertDestinationEmail(ctx context.Context, exec bob.Executor, related *CommsEmailSetter) error {
func (commsEmailLog0 *CommsEmailLog) InsertDestinationEmailContact(ctx context.Context, exec bob.Executor, related *CommsEmailContactSetter) error {
var err error
commsEmail1, err := CommsEmails.Insert(related).One(ctx, exec)
commsEmailContact1, err := CommsEmailContacts.Insert(related).One(ctx, exec)
if err != nil {
return fmt.Errorf("inserting related objects: %w", err)
}
_, err = attachCommsEmailLogDestinationEmail0(ctx, exec, 1, commsEmailLog0, commsEmail1)
_, err = attachCommsEmailLogDestinationEmailContact0(ctx, exec, 1, commsEmailLog0, commsEmailContact1)
if err != nil {
return err
}
commsEmailLog0.R.DestinationEmail = commsEmail1
commsEmailLog0.R.DestinationEmailContact = commsEmailContact1
commsEmail1.R.DestinationEmailLogs = append(commsEmail1.R.DestinationEmailLogs, commsEmailLog0)
commsEmailContact1.R.DestinationEmailLogs = append(commsEmailContact1.R.DestinationEmailLogs, commsEmailLog0)
return nil
}
func (commsEmailLog0 *CommsEmailLog) AttachDestinationEmail(ctx context.Context, exec bob.Executor, commsEmail1 *CommsEmail) error {
func (commsEmailLog0 *CommsEmailLog) AttachDestinationEmailContact(ctx context.Context, exec bob.Executor, commsEmailContact1 *CommsEmailContact) error {
var err error
_, err = attachCommsEmailLogDestinationEmail0(ctx, exec, 1, commsEmailLog0, commsEmail1)
_, err = attachCommsEmailLogDestinationEmailContact0(ctx, exec, 1, commsEmailLog0, commsEmailContact1)
if err != nil {
return err
}
commsEmailLog0.R.DestinationEmail = commsEmail1
commsEmailLog0.R.DestinationEmailContact = commsEmailContact1
commsEmail1.R.DestinationEmailLogs = append(commsEmail1.R.DestinationEmailLogs, commsEmailLog0)
commsEmailContact1.R.DestinationEmailLogs = append(commsEmailContact1.R.DestinationEmailLogs, commsEmailLog0)
return nil
}
func attachCommsEmailLogSourcePhone0(ctx context.Context, exec bob.Executor, count int, commsEmailLog0 *CommsEmailLog, commsPhone1 *CommsPhone) (*CommsEmailLog, error) {
func attachCommsEmailLogTemplateEmailTemplate0(ctx context.Context, exec bob.Executor, count int, commsEmailLog0 *CommsEmailLog, commsEmailTemplate1 *CommsEmailTemplate) (*CommsEmailLog, error) {
setter := &CommsEmailLogSetter{
Source: omit.From(commsPhone1.E164),
TemplateID: omitnull.From(commsEmailTemplate1.ID),
}
err := commsEmailLog0.Update(ctx, exec, setter)
if err != nil {
return nil, fmt.Errorf("attachCommsEmailLogSourcePhone0: %w", err)
return nil, fmt.Errorf("attachCommsEmailLogTemplateEmailTemplate0: %w", err)
}
return commsEmailLog0, nil
}
func (commsEmailLog0 *CommsEmailLog) InsertSourcePhone(ctx context.Context, exec bob.Executor, related *CommsPhoneSetter) error {
func (commsEmailLog0 *CommsEmailLog) InsertTemplateEmailTemplate(ctx context.Context, exec bob.Executor, related *CommsEmailTemplateSetter) error {
var err error
commsPhone1, err := CommsPhones.Insert(related).One(ctx, exec)
commsEmailTemplate1, err := CommsEmailTemplates.Insert(related).One(ctx, exec)
if err != nil {
return fmt.Errorf("inserting related objects: %w", err)
}
_, err = attachCommsEmailLogSourcePhone0(ctx, exec, 1, commsEmailLog0, commsPhone1)
_, err = attachCommsEmailLogTemplateEmailTemplate0(ctx, exec, 1, commsEmailLog0, commsEmailTemplate1)
if err != nil {
return err
}
commsEmailLog0.R.SourcePhone = commsPhone1
commsEmailLog0.R.TemplateEmailTemplate = commsEmailTemplate1
commsPhone1.R.SourceEmailLogs = append(commsPhone1.R.SourceEmailLogs, commsEmailLog0)
commsEmailTemplate1.R.TemplateEmailLogs = append(commsEmailTemplate1.R.TemplateEmailLogs, commsEmailLog0)
return nil
}
func (commsEmailLog0 *CommsEmailLog) AttachSourcePhone(ctx context.Context, exec bob.Executor, commsPhone1 *CommsPhone) error {
func (commsEmailLog0 *CommsEmailLog) AttachTemplateEmailTemplate(ctx context.Context, exec bob.Executor, commsEmailTemplate1 *CommsEmailTemplate) error {
var err error
_, err = attachCommsEmailLogSourcePhone0(ctx, exec, 1, commsEmailLog0, commsPhone1)
_, err = attachCommsEmailLogTemplateEmailTemplate0(ctx, exec, 1, commsEmailLog0, commsEmailTemplate1)
if err != nil {
return err
}
commsEmailLog0.R.SourcePhone = commsPhone1
commsEmailLog0.R.TemplateEmailTemplate = commsEmailTemplate1
commsPhone1.R.SourceEmailLogs = append(commsPhone1.R.SourceEmailLogs, commsEmailLog0)
commsEmailTemplate1.R.TemplateEmailLogs = append(commsEmailTemplate1.R.TemplateEmailLogs, commsEmailLog0)
return nil
}
type commsEmailLogWhere[Q psql.Filterable] struct {
Created psql.WhereMod[Q, time.Time]
Destination psql.WhereMod[Q, string]
Source psql.WhereMod[Q, string]
Type psql.WhereMod[Q, enums.CommsMessagetypeemail]
ID psql.WhereMod[Q, int32]
Created psql.WhereMod[Q, time.Time]
DeliveryStatus psql.WhereMod[Q, string]
Destination psql.WhereMod[Q, string]
PublicID psql.WhereMod[Q, string]
SentAt psql.WhereNullMod[Q, time.Time]
Source psql.WhereMod[Q, string]
Subject psql.WhereMod[Q, string]
TemplateID psql.WhereNullMod[Q, int32]
TemplateData psql.WhereMod[Q, pgtypes.HStore]
Type psql.WhereMod[Q, enums.CommsMessagetypeemail]
}
func (commsEmailLogWhere[Q]) AliasedAs(alias string) commsEmailLogWhere[Q] {
@ -592,10 +744,17 @@ func (commsEmailLogWhere[Q]) AliasedAs(alias string) commsEmailLogWhere[Q] {
func buildCommsEmailLogWhere[Q psql.Filterable](cols commsEmailLogColumns) commsEmailLogWhere[Q] {
return commsEmailLogWhere[Q]{
Created: psql.Where[Q, time.Time](cols.Created),
Destination: psql.Where[Q, string](cols.Destination),
Source: psql.Where[Q, string](cols.Source),
Type: psql.Where[Q, enums.CommsMessagetypeemail](cols.Type),
ID: psql.Where[Q, int32](cols.ID),
Created: psql.Where[Q, time.Time](cols.Created),
DeliveryStatus: psql.Where[Q, string](cols.DeliveryStatus),
Destination: psql.Where[Q, string](cols.Destination),
PublicID: psql.Where[Q, string](cols.PublicID),
SentAt: psql.WhereNull[Q, time.Time](cols.SentAt),
Source: psql.Where[Q, string](cols.Source),
Subject: psql.Where[Q, string](cols.Subject),
TemplateID: psql.WhereNull[Q, int32](cols.TemplateID),
TemplateData: psql.Where[Q, pgtypes.HStore](cols.TemplateData),
Type: psql.Where[Q, enums.CommsMessagetypeemail](cols.Type),
}
}
@ -605,28 +764,28 @@ func (o *CommsEmailLog) Preload(name string, retrieved any) error {
}
switch name {
case "DestinationEmail":
rel, ok := retrieved.(*CommsEmail)
case "DestinationEmailContact":
rel, ok := retrieved.(*CommsEmailContact)
if !ok {
return fmt.Errorf("commsEmailLog cannot load %T as %q", retrieved, name)
}
o.R.DestinationEmail = rel
o.R.DestinationEmailContact = rel
if rel != nil {
rel.R.DestinationEmailLogs = CommsEmailLogSlice{o}
}
return nil
case "SourcePhone":
rel, ok := retrieved.(*CommsPhone)
case "TemplateEmailTemplate":
rel, ok := retrieved.(*CommsEmailTemplate)
if !ok {
return fmt.Errorf("commsEmailLog cannot load %T as %q", retrieved, name)
}
o.R.SourcePhone = rel
o.R.TemplateEmailTemplate = rel
if rel != nil {
rel.R.SourceEmailLogs = CommsEmailLogSlice{o}
rel.R.TemplateEmailLogs = CommsEmailLogSlice{o}
}
return nil
default:
@ -635,97 +794,97 @@ func (o *CommsEmailLog) Preload(name string, retrieved any) error {
}
type commsEmailLogPreloader struct {
DestinationEmail func(...psql.PreloadOption) psql.Preloader
SourcePhone func(...psql.PreloadOption) psql.Preloader
DestinationEmailContact func(...psql.PreloadOption) psql.Preloader
TemplateEmailTemplate func(...psql.PreloadOption) psql.Preloader
}
func buildCommsEmailLogPreloader() commsEmailLogPreloader {
return commsEmailLogPreloader{
DestinationEmail: func(opts ...psql.PreloadOption) psql.Preloader {
return psql.Preload[*CommsEmail, CommsEmailSlice](psql.PreloadRel{
Name: "DestinationEmail",
DestinationEmailContact: func(opts ...psql.PreloadOption) psql.Preloader {
return psql.Preload[*CommsEmailContact, CommsEmailContactSlice](psql.PreloadRel{
Name: "DestinationEmailContact",
Sides: []psql.PreloadSide{
{
From: CommsEmailLogs,
To: CommsEmails,
To: CommsEmailContacts,
FromColumns: []string{"destination"},
ToColumns: []string{"address"},
},
},
}, CommsEmails.Columns.Names(), opts...)
}, CommsEmailContacts.Columns.Names(), opts...)
},
SourcePhone: func(opts ...psql.PreloadOption) psql.Preloader {
return psql.Preload[*CommsPhone, CommsPhoneSlice](psql.PreloadRel{
Name: "SourcePhone",
TemplateEmailTemplate: func(opts ...psql.PreloadOption) psql.Preloader {
return psql.Preload[*CommsEmailTemplate, CommsEmailTemplateSlice](psql.PreloadRel{
Name: "TemplateEmailTemplate",
Sides: []psql.PreloadSide{
{
From: CommsEmailLogs,
To: CommsPhones,
FromColumns: []string{"source"},
ToColumns: []string{"e164"},
To: CommsEmailTemplates,
FromColumns: []string{"template_id"},
ToColumns: []string{"id"},
},
},
}, CommsPhones.Columns.Names(), opts...)
}, CommsEmailTemplates.Columns.Names(), opts...)
},
}
}
type commsEmailLogThenLoader[Q orm.Loadable] struct {
DestinationEmail func(...bob.Mod[*dialect.SelectQuery]) orm.Loader[Q]
SourcePhone func(...bob.Mod[*dialect.SelectQuery]) orm.Loader[Q]
DestinationEmailContact func(...bob.Mod[*dialect.SelectQuery]) orm.Loader[Q]
TemplateEmailTemplate func(...bob.Mod[*dialect.SelectQuery]) orm.Loader[Q]
}
func buildCommsEmailLogThenLoader[Q orm.Loadable]() commsEmailLogThenLoader[Q] {
type DestinationEmailLoadInterface interface {
LoadDestinationEmail(context.Context, bob.Executor, ...bob.Mod[*dialect.SelectQuery]) error
type DestinationEmailContactLoadInterface interface {
LoadDestinationEmailContact(context.Context, bob.Executor, ...bob.Mod[*dialect.SelectQuery]) error
}
type SourcePhoneLoadInterface interface {
LoadSourcePhone(context.Context, bob.Executor, ...bob.Mod[*dialect.SelectQuery]) error
type TemplateEmailTemplateLoadInterface interface {
LoadTemplateEmailTemplate(context.Context, bob.Executor, ...bob.Mod[*dialect.SelectQuery]) error
}
return commsEmailLogThenLoader[Q]{
DestinationEmail: thenLoadBuilder[Q](
"DestinationEmail",
func(ctx context.Context, exec bob.Executor, retrieved DestinationEmailLoadInterface, mods ...bob.Mod[*dialect.SelectQuery]) error {
return retrieved.LoadDestinationEmail(ctx, exec, mods...)
DestinationEmailContact: thenLoadBuilder[Q](
"DestinationEmailContact",
func(ctx context.Context, exec bob.Executor, retrieved DestinationEmailContactLoadInterface, mods ...bob.Mod[*dialect.SelectQuery]) error {
return retrieved.LoadDestinationEmailContact(ctx, exec, mods...)
},
),
SourcePhone: thenLoadBuilder[Q](
"SourcePhone",
func(ctx context.Context, exec bob.Executor, retrieved SourcePhoneLoadInterface, mods ...bob.Mod[*dialect.SelectQuery]) error {
return retrieved.LoadSourcePhone(ctx, exec, mods...)
TemplateEmailTemplate: thenLoadBuilder[Q](
"TemplateEmailTemplate",
func(ctx context.Context, exec bob.Executor, retrieved TemplateEmailTemplateLoadInterface, mods ...bob.Mod[*dialect.SelectQuery]) error {
return retrieved.LoadTemplateEmailTemplate(ctx, exec, mods...)
},
),
}
}
// LoadDestinationEmail loads the commsEmailLog's DestinationEmail into the .R struct
func (o *CommsEmailLog) LoadDestinationEmail(ctx context.Context, exec bob.Executor, mods ...bob.Mod[*dialect.SelectQuery]) error {
// LoadDestinationEmailContact loads the commsEmailLog's DestinationEmailContact into the .R struct
func (o *CommsEmailLog) LoadDestinationEmailContact(ctx context.Context, exec bob.Executor, mods ...bob.Mod[*dialect.SelectQuery]) error {
if o == nil {
return nil
}
// Reset the relationship
o.R.DestinationEmail = nil
o.R.DestinationEmailContact = nil
related, err := o.DestinationEmail(mods...).One(ctx, exec)
related, err := o.DestinationEmailContact(mods...).One(ctx, exec)
if err != nil {
return err
}
related.R.DestinationEmailLogs = CommsEmailLogSlice{o}
o.R.DestinationEmail = related
o.R.DestinationEmailContact = related
return nil
}
// LoadDestinationEmail loads the commsEmailLog's DestinationEmail into the .R struct
func (os CommsEmailLogSlice) LoadDestinationEmail(ctx context.Context, exec bob.Executor, mods ...bob.Mod[*dialect.SelectQuery]) error {
// LoadDestinationEmailContact loads the commsEmailLog's DestinationEmailContact into the .R struct
func (os CommsEmailLogSlice) LoadDestinationEmailContact(ctx context.Context, exec bob.Executor, mods ...bob.Mod[*dialect.SelectQuery]) error {
if len(os) == 0 {
return nil
}
commsEmails, err := os.DestinationEmail(mods...).All(ctx, exec)
commsEmailContacts, err := os.DestinationEmailContact(mods...).All(ctx, exec)
if err != nil {
return err
}
@ -735,7 +894,7 @@ func (os CommsEmailLogSlice) LoadDestinationEmail(ctx context.Context, exec bob.
continue
}
for _, rel := range commsEmails {
for _, rel := range commsEmailContacts {
if !(o.Destination == rel.Address) {
continue
@ -743,7 +902,7 @@ func (os CommsEmailLogSlice) LoadDestinationEmail(ctx context.Context, exec bob.
rel.R.DestinationEmailLogs = append(rel.R.DestinationEmailLogs, o)
o.R.DestinationEmail = rel
o.R.DestinationEmailContact = rel
break
}
}
@ -751,33 +910,33 @@ func (os CommsEmailLogSlice) LoadDestinationEmail(ctx context.Context, exec bob.
return nil
}
// LoadSourcePhone loads the commsEmailLog's SourcePhone into the .R struct
func (o *CommsEmailLog) LoadSourcePhone(ctx context.Context, exec bob.Executor, mods ...bob.Mod[*dialect.SelectQuery]) error {
// LoadTemplateEmailTemplate loads the commsEmailLog's TemplateEmailTemplate into the .R struct
func (o *CommsEmailLog) LoadTemplateEmailTemplate(ctx context.Context, exec bob.Executor, mods ...bob.Mod[*dialect.SelectQuery]) error {
if o == nil {
return nil
}
// Reset the relationship
o.R.SourcePhone = nil
o.R.TemplateEmailTemplate = nil
related, err := o.SourcePhone(mods...).One(ctx, exec)
related, err := o.TemplateEmailTemplate(mods...).One(ctx, exec)
if err != nil {
return err
}
related.R.SourceEmailLogs = CommsEmailLogSlice{o}
related.R.TemplateEmailLogs = CommsEmailLogSlice{o}
o.R.SourcePhone = related
o.R.TemplateEmailTemplate = related
return nil
}
// LoadSourcePhone loads the commsEmailLog's SourcePhone into the .R struct
func (os CommsEmailLogSlice) LoadSourcePhone(ctx context.Context, exec bob.Executor, mods ...bob.Mod[*dialect.SelectQuery]) error {
// LoadTemplateEmailTemplate loads the commsEmailLog's TemplateEmailTemplate into the .R struct
func (os CommsEmailLogSlice) LoadTemplateEmailTemplate(ctx context.Context, exec bob.Executor, mods ...bob.Mod[*dialect.SelectQuery]) error {
if len(os) == 0 {
return nil
}
commsPhones, err := os.SourcePhone(mods...).All(ctx, exec)
commsEmailTemplates, err := os.TemplateEmailTemplate(mods...).All(ctx, exec)
if err != nil {
return err
}
@ -787,15 +946,18 @@ func (os CommsEmailLogSlice) LoadSourcePhone(ctx context.Context, exec bob.Execu
continue
}
for _, rel := range commsPhones {
if !(o.Source == rel.E164) {
for _, rel := range commsEmailTemplates {
if !o.TemplateID.IsValue() {
continue
}
rel.R.SourceEmailLogs = append(rel.R.SourceEmailLogs, o)
if !(o.TemplateID.IsValue() && o.TemplateID.MustGet() == rel.ID) {
continue
}
o.R.SourcePhone = rel
rel.R.TemplateEmailLogs = append(rel.R.TemplateEmailLogs, o)
o.R.TemplateEmailTemplate = rel
break
}
}
@ -804,9 +966,9 @@ func (os CommsEmailLogSlice) LoadSourcePhone(ctx context.Context, exec bob.Execu
}
type commsEmailLogJoins[Q dialect.Joinable] struct {
typ string
DestinationEmail modAs[Q, commsEmailColumns]
SourcePhone modAs[Q, commsPhoneColumns]
typ string
DestinationEmailContact modAs[Q, commsEmailContactColumns]
TemplateEmailTemplate modAs[Q, commsEmailTemplateColumns]
}
func (j commsEmailLogJoins[Q]) aliasedAs(alias string) commsEmailLogJoins[Q] {
@ -816,13 +978,13 @@ func (j commsEmailLogJoins[Q]) aliasedAs(alias string) commsEmailLogJoins[Q] {
func buildCommsEmailLogJoins[Q dialect.Joinable](cols commsEmailLogColumns, typ string) commsEmailLogJoins[Q] {
return commsEmailLogJoins[Q]{
typ: typ,
DestinationEmail: modAs[Q, commsEmailColumns]{
c: CommsEmails.Columns,
f: func(to commsEmailColumns) bob.Mod[Q] {
DestinationEmailContact: modAs[Q, commsEmailContactColumns]{
c: CommsEmailContacts.Columns,
f: func(to commsEmailContactColumns) bob.Mod[Q] {
mods := make(mods.QueryMods[Q], 0, 1)
{
mods = append(mods, dialect.Join[Q](typ, CommsEmails.Name().As(to.Alias())).On(
mods = append(mods, dialect.Join[Q](typ, CommsEmailContacts.Name().As(to.Alias())).On(
to.Address.EQ(cols.Destination),
))
}
@ -830,14 +992,14 @@ func buildCommsEmailLogJoins[Q dialect.Joinable](cols commsEmailLogColumns, typ
return mods
},
},
SourcePhone: modAs[Q, commsPhoneColumns]{
c: CommsPhones.Columns,
f: func(to commsPhoneColumns) bob.Mod[Q] {
TemplateEmailTemplate: modAs[Q, commsEmailTemplateColumns]{
c: CommsEmailTemplates.Columns,
f: func(to commsEmailTemplateColumns) bob.Mod[Q] {
mods := make(mods.QueryMods[Q], 0, 1)
{
mods = append(mods, dialect.Join[Q](typ, CommsPhones.Name().As(to.Alias())).On(
to.E164.EQ(cols.Source),
mods = append(mods, dialect.Join[Q](typ, CommsEmailTemplates.Name().As(to.Alias())).On(
to.ID.EQ(cols.TemplateID),
))
}

View file

@ -0,0 +1,869 @@
// Code generated by BobGen psql v0.42.1. 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"
enums "github.com/Gleipnir-Technology/nidus-sync/db/enums"
"github.com/aarondl/opt/null"
"github.com/aarondl/opt/omit"
"github.com/aarondl/opt/omitnull"
"github.com/stephenafamo/bob"
"github.com/stephenafamo/bob/dialect/psql"
"github.com/stephenafamo/bob/dialect/psql/dialect"
"github.com/stephenafamo/bob/dialect/psql/dm"
"github.com/stephenafamo/bob/dialect/psql/sm"
"github.com/stephenafamo/bob/dialect/psql/um"
"github.com/stephenafamo/bob/expr"
"github.com/stephenafamo/bob/mods"
"github.com/stephenafamo/bob/orm"
"github.com/stephenafamo/bob/types/pgtypes"
)
// CommsEmailTemplate is an object representing the database table.
type CommsEmailTemplate struct {
ContentHTML string `db:"content_html" `
ContentTXT string `db:"content_txt" `
ContentHashHTML string `db:"content_hash_html" `
ContentHashTXT string `db:"content_hash_txt" `
Created time.Time `db:"created" `
ID int32 `db:"id,pk" `
Superceded null.Val[time.Time] `db:"superceded" `
MessageType enums.CommsMessagetypeemail `db:"message_type" `
R commsEmailTemplateR `db:"-" `
C commsEmailTemplateC `db:"-" `
}
// CommsEmailTemplateSlice is an alias for a slice of pointers to CommsEmailTemplate.
// This should almost always be used instead of []*CommsEmailTemplate.
type CommsEmailTemplateSlice []*CommsEmailTemplate
// CommsEmailTemplates contains methods to work with the email_template table
var CommsEmailTemplates = psql.NewTablex[*CommsEmailTemplate, CommsEmailTemplateSlice, *CommsEmailTemplateSetter]("comms", "email_template", buildCommsEmailTemplateColumns("comms.email_template"))
// CommsEmailTemplatesQuery is a query on the email_template table
type CommsEmailTemplatesQuery = *psql.ViewQuery[*CommsEmailTemplate, CommsEmailTemplateSlice]
// commsEmailTemplateR is where relationships are stored.
type commsEmailTemplateR struct {
TemplateEmailLogs CommsEmailLogSlice // comms.email_log.email_log_template_id_fkey
}
func buildCommsEmailTemplateColumns(alias string) commsEmailTemplateColumns {
return commsEmailTemplateColumns{
ColumnsExpr: expr.NewColumnsExpr(
"content_html", "content_txt", "content_hash_html", "content_hash_txt", "created", "id", "superceded", "message_type",
).WithParent("comms.email_template"),
tableAlias: alias,
ContentHTML: psql.Quote(alias, "content_html"),
ContentTXT: psql.Quote(alias, "content_txt"),
ContentHashHTML: psql.Quote(alias, "content_hash_html"),
ContentHashTXT: psql.Quote(alias, "content_hash_txt"),
Created: psql.Quote(alias, "created"),
ID: psql.Quote(alias, "id"),
Superceded: psql.Quote(alias, "superceded"),
MessageType: psql.Quote(alias, "message_type"),
}
}
type commsEmailTemplateColumns struct {
expr.ColumnsExpr
tableAlias string
ContentHTML psql.Expression
ContentTXT psql.Expression
ContentHashHTML psql.Expression
ContentHashTXT psql.Expression
Created psql.Expression
ID psql.Expression
Superceded psql.Expression
MessageType psql.Expression
}
func (c commsEmailTemplateColumns) Alias() string {
return c.tableAlias
}
func (commsEmailTemplateColumns) AliasedAs(alias string) commsEmailTemplateColumns {
return buildCommsEmailTemplateColumns(alias)
}
// CommsEmailTemplateSetter is used for insert/upsert/update operations
// All values are optional, and do not have to be set
// Generated columns are not included
type CommsEmailTemplateSetter struct {
ContentHTML omit.Val[string] `db:"content_html" `
ContentTXT omit.Val[string] `db:"content_txt" `
ContentHashHTML omit.Val[string] `db:"content_hash_html" `
ContentHashTXT omit.Val[string] `db:"content_hash_txt" `
Created omit.Val[time.Time] `db:"created" `
ID omit.Val[int32] `db:"id,pk" `
Superceded omitnull.Val[time.Time] `db:"superceded" `
MessageType omit.Val[enums.CommsMessagetypeemail] `db:"message_type" `
}
func (s CommsEmailTemplateSetter) SetColumns() []string {
vals := make([]string, 0, 8)
if s.ContentHTML.IsValue() {
vals = append(vals, "content_html")
}
if s.ContentTXT.IsValue() {
vals = append(vals, "content_txt")
}
if s.ContentHashHTML.IsValue() {
vals = append(vals, "content_hash_html")
}
if s.ContentHashTXT.IsValue() {
vals = append(vals, "content_hash_txt")
}
if s.Created.IsValue() {
vals = append(vals, "created")
}
if s.ID.IsValue() {
vals = append(vals, "id")
}
if !s.Superceded.IsUnset() {
vals = append(vals, "superceded")
}
if s.MessageType.IsValue() {
vals = append(vals, "message_type")
}
return vals
}
func (s CommsEmailTemplateSetter) Overwrite(t *CommsEmailTemplate) {
if s.ContentHTML.IsValue() {
t.ContentHTML = s.ContentHTML.MustGet()
}
if s.ContentTXT.IsValue() {
t.ContentTXT = s.ContentTXT.MustGet()
}
if s.ContentHashHTML.IsValue() {
t.ContentHashHTML = s.ContentHashHTML.MustGet()
}
if s.ContentHashTXT.IsValue() {
t.ContentHashTXT = s.ContentHashTXT.MustGet()
}
if s.Created.IsValue() {
t.Created = s.Created.MustGet()
}
if s.ID.IsValue() {
t.ID = s.ID.MustGet()
}
if !s.Superceded.IsUnset() {
t.Superceded = s.Superceded.MustGetNull()
}
if s.MessageType.IsValue() {
t.MessageType = s.MessageType.MustGet()
}
}
func (s *CommsEmailTemplateSetter) Apply(q *dialect.InsertQuery) {
q.AppendHooks(func(ctx context.Context, exec bob.Executor) (context.Context, error) {
return CommsEmailTemplates.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, 8)
if s.ContentHTML.IsValue() {
vals[0] = psql.Arg(s.ContentHTML.MustGet())
} else {
vals[0] = psql.Raw("DEFAULT")
}
if s.ContentTXT.IsValue() {
vals[1] = psql.Arg(s.ContentTXT.MustGet())
} else {
vals[1] = psql.Raw("DEFAULT")
}
if s.ContentHashHTML.IsValue() {
vals[2] = psql.Arg(s.ContentHashHTML.MustGet())
} else {
vals[2] = psql.Raw("DEFAULT")
}
if s.ContentHashTXT.IsValue() {
vals[3] = psql.Arg(s.ContentHashTXT.MustGet())
} else {
vals[3] = psql.Raw("DEFAULT")
}
if s.Created.IsValue() {
vals[4] = psql.Arg(s.Created.MustGet())
} else {
vals[4] = psql.Raw("DEFAULT")
}
if s.ID.IsValue() {
vals[5] = psql.Arg(s.ID.MustGet())
} else {
vals[5] = psql.Raw("DEFAULT")
}
if !s.Superceded.IsUnset() {
vals[6] = psql.Arg(s.Superceded.MustGetNull())
} else {
vals[6] = psql.Raw("DEFAULT")
}
if s.MessageType.IsValue() {
vals[7] = psql.Arg(s.MessageType.MustGet())
} else {
vals[7] = psql.Raw("DEFAULT")
}
return bob.ExpressSlice(ctx, w, d, start, vals, "", ", ", "")
}))
}
func (s CommsEmailTemplateSetter) UpdateMod() bob.Mod[*dialect.UpdateQuery] {
return um.Set(s.Expressions()...)
}
func (s CommsEmailTemplateSetter) Expressions(prefix ...string) []bob.Expression {
exprs := make([]bob.Expression, 0, 8)
if s.ContentHTML.IsValue() {
exprs = append(exprs, expr.Join{Sep: " = ", Exprs: []bob.Expression{
psql.Quote(append(prefix, "content_html")...),
psql.Arg(s.ContentHTML),
}})
}
if s.ContentTXT.IsValue() {
exprs = append(exprs, expr.Join{Sep: " = ", Exprs: []bob.Expression{
psql.Quote(append(prefix, "content_txt")...),
psql.Arg(s.ContentTXT),
}})
}
if s.ContentHashHTML.IsValue() {
exprs = append(exprs, expr.Join{Sep: " = ", Exprs: []bob.Expression{
psql.Quote(append(prefix, "content_hash_html")...),
psql.Arg(s.ContentHashHTML),
}})
}
if s.ContentHashTXT.IsValue() {
exprs = append(exprs, expr.Join{Sep: " = ", Exprs: []bob.Expression{
psql.Quote(append(prefix, "content_hash_txt")...),
psql.Arg(s.ContentHashTXT),
}})
}
if s.Created.IsValue() {
exprs = append(exprs, expr.Join{Sep: " = ", Exprs: []bob.Expression{
psql.Quote(append(prefix, "created")...),
psql.Arg(s.Created),
}})
}
if s.ID.IsValue() {
exprs = append(exprs, expr.Join{Sep: " = ", Exprs: []bob.Expression{
psql.Quote(append(prefix, "id")...),
psql.Arg(s.ID),
}})
}
if !s.Superceded.IsUnset() {
exprs = append(exprs, expr.Join{Sep: " = ", Exprs: []bob.Expression{
psql.Quote(append(prefix, "superceded")...),
psql.Arg(s.Superceded),
}})
}
if s.MessageType.IsValue() {
exprs = append(exprs, expr.Join{Sep: " = ", Exprs: []bob.Expression{
psql.Quote(append(prefix, "message_type")...),
psql.Arg(s.MessageType),
}})
}
return exprs
}
// FindCommsEmailTemplate retrieves a single record by primary key
// If cols is empty Find will return all columns.
func FindCommsEmailTemplate(ctx context.Context, exec bob.Executor, IDPK int32, cols ...string) (*CommsEmailTemplate, error) {
if len(cols) == 0 {
return CommsEmailTemplates.Query(
sm.Where(CommsEmailTemplates.Columns.ID.EQ(psql.Arg(IDPK))),
).One(ctx, exec)
}
return CommsEmailTemplates.Query(
sm.Where(CommsEmailTemplates.Columns.ID.EQ(psql.Arg(IDPK))),
sm.Columns(CommsEmailTemplates.Columns.Only(cols...)),
).One(ctx, exec)
}
// CommsEmailTemplateExists checks the presence of a single record by primary key
func CommsEmailTemplateExists(ctx context.Context, exec bob.Executor, IDPK int32) (bool, error) {
return CommsEmailTemplates.Query(
sm.Where(CommsEmailTemplates.Columns.ID.EQ(psql.Arg(IDPK))),
).Exists(ctx, exec)
}
// AfterQueryHook is called after CommsEmailTemplate is retrieved from the database
func (o *CommsEmailTemplate) AfterQueryHook(ctx context.Context, exec bob.Executor, queryType bob.QueryType) error {
var err error
switch queryType {
case bob.QueryTypeSelect:
ctx, err = CommsEmailTemplates.AfterSelectHooks.RunHooks(ctx, exec, CommsEmailTemplateSlice{o})
case bob.QueryTypeInsert:
ctx, err = CommsEmailTemplates.AfterInsertHooks.RunHooks(ctx, exec, CommsEmailTemplateSlice{o})
case bob.QueryTypeUpdate:
ctx, err = CommsEmailTemplates.AfterUpdateHooks.RunHooks(ctx, exec, CommsEmailTemplateSlice{o})
case bob.QueryTypeDelete:
ctx, err = CommsEmailTemplates.AfterDeleteHooks.RunHooks(ctx, exec, CommsEmailTemplateSlice{o})
}
return err
}
// primaryKeyVals returns the primary key values of the CommsEmailTemplate
func (o *CommsEmailTemplate) primaryKeyVals() bob.Expression {
return psql.Arg(o.ID)
}
func (o *CommsEmailTemplate) pkEQ() dialect.Expression {
return psql.Quote("comms.email_template", "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 CommsEmailTemplate
func (o *CommsEmailTemplate) Update(ctx context.Context, exec bob.Executor, s *CommsEmailTemplateSetter) error {
v, err := CommsEmailTemplates.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 CommsEmailTemplate record with an executor
func (o *CommsEmailTemplate) Delete(ctx context.Context, exec bob.Executor) error {
_, err := CommsEmailTemplates.Delete(dm.Where(o.pkEQ())).Exec(ctx, exec)
return err
}
// Reload refreshes the CommsEmailTemplate using the executor
func (o *CommsEmailTemplate) Reload(ctx context.Context, exec bob.Executor) error {
o2, err := CommsEmailTemplates.Query(
sm.Where(CommsEmailTemplates.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 CommsEmailTemplateSlice is retrieved from the database
func (o CommsEmailTemplateSlice) AfterQueryHook(ctx context.Context, exec bob.Executor, queryType bob.QueryType) error {
var err error
switch queryType {
case bob.QueryTypeSelect:
ctx, err = CommsEmailTemplates.AfterSelectHooks.RunHooks(ctx, exec, o)
case bob.QueryTypeInsert:
ctx, err = CommsEmailTemplates.AfterInsertHooks.RunHooks(ctx, exec, o)
case bob.QueryTypeUpdate:
ctx, err = CommsEmailTemplates.AfterUpdateHooks.RunHooks(ctx, exec, o)
case bob.QueryTypeDelete:
ctx, err = CommsEmailTemplates.AfterDeleteHooks.RunHooks(ctx, exec, o)
}
return err
}
func (o CommsEmailTemplateSlice) pkIN() dialect.Expression {
if len(o) == 0 {
return psql.Raw("NULL")
}
return psql.Quote("comms.email_template", "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 CommsEmailTemplateSlice) copyMatchingRows(from ...*CommsEmailTemplate) {
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 CommsEmailTemplateSlice) 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 CommsEmailTemplates.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 *CommsEmailTemplate:
o.copyMatchingRows(retrieved)
case []*CommsEmailTemplate:
o.copyMatchingRows(retrieved...)
case CommsEmailTemplateSlice:
o.copyMatchingRows(retrieved...)
default:
// If the retrieved value is not a CommsEmailTemplate or a slice of CommsEmailTemplate
// then run the AfterUpdateHooks on the slice
_, err = CommsEmailTemplates.AfterUpdateHooks.RunHooks(ctx, exec, o)
}
return err
}))
q.AppendWhere(o.pkIN())
})
}
// DeleteMod modifies an delete query with "WHERE primary_key IN (o...)"
func (o CommsEmailTemplateSlice) 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 CommsEmailTemplates.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 *CommsEmailTemplate:
o.copyMatchingRows(retrieved)
case []*CommsEmailTemplate:
o.copyMatchingRows(retrieved...)
case CommsEmailTemplateSlice:
o.copyMatchingRows(retrieved...)
default:
// If the retrieved value is not a CommsEmailTemplate or a slice of CommsEmailTemplate
// then run the AfterDeleteHooks on the slice
_, err = CommsEmailTemplates.AfterDeleteHooks.RunHooks(ctx, exec, o)
}
return err
}))
q.AppendWhere(o.pkIN())
})
}
func (o CommsEmailTemplateSlice) UpdateAll(ctx context.Context, exec bob.Executor, vals CommsEmailTemplateSetter) error {
if len(o) == 0 {
return nil
}
_, err := CommsEmailTemplates.Update(vals.UpdateMod(), o.UpdateMod()).All(ctx, exec)
return err
}
func (o CommsEmailTemplateSlice) DeleteAll(ctx context.Context, exec bob.Executor) error {
if len(o) == 0 {
return nil
}
_, err := CommsEmailTemplates.Delete(o.DeleteMod()).Exec(ctx, exec)
return err
}
func (o CommsEmailTemplateSlice) ReloadAll(ctx context.Context, exec bob.Executor) error {
if len(o) == 0 {
return nil
}
o2, err := CommsEmailTemplates.Query(sm.Where(o.pkIN())).All(ctx, exec)
if err != nil {
return err
}
o.copyMatchingRows(o2...)
return nil
}
// TemplateEmailLogs starts a query for related objects on comms.email_log
func (o *CommsEmailTemplate) TemplateEmailLogs(mods ...bob.Mod[*dialect.SelectQuery]) CommsEmailLogsQuery {
return CommsEmailLogs.Query(append(mods,
sm.Where(CommsEmailLogs.Columns.TemplateID.EQ(psql.Arg(o.ID))),
)...)
}
func (os CommsEmailTemplateSlice) TemplateEmailLogs(mods ...bob.Mod[*dialect.SelectQuery]) CommsEmailLogsQuery {
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 CommsEmailLogs.Query(append(mods,
sm.Where(psql.Group(CommsEmailLogs.Columns.TemplateID).OP("IN", PKArgExpr)),
)...)
}
func insertCommsEmailTemplateTemplateEmailLogs0(ctx context.Context, exec bob.Executor, commsEmailLogs1 []*CommsEmailLogSetter, commsEmailTemplate0 *CommsEmailTemplate) (CommsEmailLogSlice, error) {
for i := range commsEmailLogs1 {
commsEmailLogs1[i].TemplateID = omitnull.From(commsEmailTemplate0.ID)
}
ret, err := CommsEmailLogs.Insert(bob.ToMods(commsEmailLogs1...)).All(ctx, exec)
if err != nil {
return ret, fmt.Errorf("insertCommsEmailTemplateTemplateEmailLogs0: %w", err)
}
return ret, nil
}
func attachCommsEmailTemplateTemplateEmailLogs0(ctx context.Context, exec bob.Executor, count int, commsEmailLogs1 CommsEmailLogSlice, commsEmailTemplate0 *CommsEmailTemplate) (CommsEmailLogSlice, error) {
setter := &CommsEmailLogSetter{
TemplateID: omitnull.From(commsEmailTemplate0.ID),
}
err := commsEmailLogs1.UpdateAll(ctx, exec, *setter)
if err != nil {
return nil, fmt.Errorf("attachCommsEmailTemplateTemplateEmailLogs0: %w", err)
}
return commsEmailLogs1, nil
}
func (commsEmailTemplate0 *CommsEmailTemplate) InsertTemplateEmailLogs(ctx context.Context, exec bob.Executor, related ...*CommsEmailLogSetter) error {
if len(related) == 0 {
return nil
}
var err error
commsEmailLogs1, err := insertCommsEmailTemplateTemplateEmailLogs0(ctx, exec, related, commsEmailTemplate0)
if err != nil {
return err
}
commsEmailTemplate0.R.TemplateEmailLogs = append(commsEmailTemplate0.R.TemplateEmailLogs, commsEmailLogs1...)
for _, rel := range commsEmailLogs1 {
rel.R.TemplateEmailTemplate = commsEmailTemplate0
}
return nil
}
func (commsEmailTemplate0 *CommsEmailTemplate) AttachTemplateEmailLogs(ctx context.Context, exec bob.Executor, related ...*CommsEmailLog) error {
if len(related) == 0 {
return nil
}
var err error
commsEmailLogs1 := CommsEmailLogSlice(related)
_, err = attachCommsEmailTemplateTemplateEmailLogs0(ctx, exec, len(related), commsEmailLogs1, commsEmailTemplate0)
if err != nil {
return err
}
commsEmailTemplate0.R.TemplateEmailLogs = append(commsEmailTemplate0.R.TemplateEmailLogs, commsEmailLogs1...)
for _, rel := range related {
rel.R.TemplateEmailTemplate = commsEmailTemplate0
}
return nil
}
type commsEmailTemplateWhere[Q psql.Filterable] struct {
ContentHTML psql.WhereMod[Q, string]
ContentTXT psql.WhereMod[Q, string]
ContentHashHTML psql.WhereMod[Q, string]
ContentHashTXT psql.WhereMod[Q, string]
Created psql.WhereMod[Q, time.Time]
ID psql.WhereMod[Q, int32]
Superceded psql.WhereNullMod[Q, time.Time]
MessageType psql.WhereMod[Q, enums.CommsMessagetypeemail]
}
func (commsEmailTemplateWhere[Q]) AliasedAs(alias string) commsEmailTemplateWhere[Q] {
return buildCommsEmailTemplateWhere[Q](buildCommsEmailTemplateColumns(alias))
}
func buildCommsEmailTemplateWhere[Q psql.Filterable](cols commsEmailTemplateColumns) commsEmailTemplateWhere[Q] {
return commsEmailTemplateWhere[Q]{
ContentHTML: psql.Where[Q, string](cols.ContentHTML),
ContentTXT: psql.Where[Q, string](cols.ContentTXT),
ContentHashHTML: psql.Where[Q, string](cols.ContentHashHTML),
ContentHashTXT: psql.Where[Q, string](cols.ContentHashTXT),
Created: psql.Where[Q, time.Time](cols.Created),
ID: psql.Where[Q, int32](cols.ID),
Superceded: psql.WhereNull[Q, time.Time](cols.Superceded),
MessageType: psql.Where[Q, enums.CommsMessagetypeemail](cols.MessageType),
}
}
func (o *CommsEmailTemplate) Preload(name string, retrieved any) error {
if o == nil {
return nil
}
switch name {
case "TemplateEmailLogs":
rels, ok := retrieved.(CommsEmailLogSlice)
if !ok {
return fmt.Errorf("commsEmailTemplate cannot load %T as %q", retrieved, name)
}
o.R.TemplateEmailLogs = rels
for _, rel := range rels {
if rel != nil {
rel.R.TemplateEmailTemplate = o
}
}
return nil
default:
return fmt.Errorf("commsEmailTemplate has no relationship %q", name)
}
}
type commsEmailTemplatePreloader struct{}
func buildCommsEmailTemplatePreloader() commsEmailTemplatePreloader {
return commsEmailTemplatePreloader{}
}
type commsEmailTemplateThenLoader[Q orm.Loadable] struct {
TemplateEmailLogs func(...bob.Mod[*dialect.SelectQuery]) orm.Loader[Q]
}
func buildCommsEmailTemplateThenLoader[Q orm.Loadable]() commsEmailTemplateThenLoader[Q] {
type TemplateEmailLogsLoadInterface interface {
LoadTemplateEmailLogs(context.Context, bob.Executor, ...bob.Mod[*dialect.SelectQuery]) error
}
return commsEmailTemplateThenLoader[Q]{
TemplateEmailLogs: thenLoadBuilder[Q](
"TemplateEmailLogs",
func(ctx context.Context, exec bob.Executor, retrieved TemplateEmailLogsLoadInterface, mods ...bob.Mod[*dialect.SelectQuery]) error {
return retrieved.LoadTemplateEmailLogs(ctx, exec, mods...)
},
),
}
}
// LoadTemplateEmailLogs loads the commsEmailTemplate's TemplateEmailLogs into the .R struct
func (o *CommsEmailTemplate) LoadTemplateEmailLogs(ctx context.Context, exec bob.Executor, mods ...bob.Mod[*dialect.SelectQuery]) error {
if o == nil {
return nil
}
// Reset the relationship
o.R.TemplateEmailLogs = nil
related, err := o.TemplateEmailLogs(mods...).All(ctx, exec)
if err != nil {
return err
}
for _, rel := range related {
rel.R.TemplateEmailTemplate = o
}
o.R.TemplateEmailLogs = related
return nil
}
// LoadTemplateEmailLogs loads the commsEmailTemplate's TemplateEmailLogs into the .R struct
func (os CommsEmailTemplateSlice) LoadTemplateEmailLogs(ctx context.Context, exec bob.Executor, mods ...bob.Mod[*dialect.SelectQuery]) error {
if len(os) == 0 {
return nil
}
commsEmailLogs, err := os.TemplateEmailLogs(mods...).All(ctx, exec)
if err != nil {
return err
}
for _, o := range os {
if o == nil {
continue
}
o.R.TemplateEmailLogs = nil
}
for _, o := range os {
if o == nil {
continue
}
for _, rel := range commsEmailLogs {
if !rel.TemplateID.IsValue() {
continue
}
if !(rel.TemplateID.IsValue() && o.ID == rel.TemplateID.MustGet()) {
continue
}
rel.R.TemplateEmailTemplate = o
o.R.TemplateEmailLogs = append(o.R.TemplateEmailLogs, rel)
}
}
return nil
}
// commsEmailTemplateC is where relationship counts are stored.
type commsEmailTemplateC struct {
TemplateEmailLogs *int64
}
// PreloadCount sets a count in the C struct by name
func (o *CommsEmailTemplate) PreloadCount(name string, count int64) error {
if o == nil {
return nil
}
switch name {
case "TemplateEmailLogs":
o.C.TemplateEmailLogs = &count
}
return nil
}
type commsEmailTemplateCountPreloader struct {
TemplateEmailLogs func(...bob.Mod[*dialect.SelectQuery]) psql.Preloader
}
func buildCommsEmailTemplateCountPreloader() commsEmailTemplateCountPreloader {
return commsEmailTemplateCountPreloader{
TemplateEmailLogs: func(mods ...bob.Mod[*dialect.SelectQuery]) psql.Preloader {
return countPreloader[*CommsEmailTemplate]("TemplateEmailLogs", func(parent string) bob.Expression {
// Build a correlated subquery: (SELECT COUNT(*) FROM related WHERE fk = parent.pk)
if parent == "" {
parent = CommsEmailTemplates.Alias()
}
subqueryMods := []bob.Mod[*dialect.SelectQuery]{
sm.Columns(psql.Raw("count(*)")),
sm.From(CommsEmailLogs.Name()),
sm.Where(psql.Quote(CommsEmailLogs.Alias(), "template_id").EQ(psql.Quote(parent, "id"))),
}
subqueryMods = append(subqueryMods, mods...)
return psql.Group(psql.Select(subqueryMods...).Expression)
})
},
}
}
type commsEmailTemplateCountThenLoader[Q orm.Loadable] struct {
TemplateEmailLogs func(...bob.Mod[*dialect.SelectQuery]) orm.Loader[Q]
}
func buildCommsEmailTemplateCountThenLoader[Q orm.Loadable]() commsEmailTemplateCountThenLoader[Q] {
type TemplateEmailLogsCountInterface interface {
LoadCountTemplateEmailLogs(context.Context, bob.Executor, ...bob.Mod[*dialect.SelectQuery]) error
}
return commsEmailTemplateCountThenLoader[Q]{
TemplateEmailLogs: countThenLoadBuilder[Q](
"TemplateEmailLogs",
func(ctx context.Context, exec bob.Executor, retrieved TemplateEmailLogsCountInterface, mods ...bob.Mod[*dialect.SelectQuery]) error {
return retrieved.LoadCountTemplateEmailLogs(ctx, exec, mods...)
},
),
}
}
// LoadCountTemplateEmailLogs loads the count of TemplateEmailLogs into the C struct
func (o *CommsEmailTemplate) LoadCountTemplateEmailLogs(ctx context.Context, exec bob.Executor, mods ...bob.Mod[*dialect.SelectQuery]) error {
if o == nil {
return nil
}
count, err := o.TemplateEmailLogs(mods...).Count(ctx, exec)
if err != nil {
return err
}
o.C.TemplateEmailLogs = &count
return nil
}
// LoadCountTemplateEmailLogs loads the count of TemplateEmailLogs for a slice
func (os CommsEmailTemplateSlice) LoadCountTemplateEmailLogs(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.LoadCountTemplateEmailLogs(ctx, exec, mods...); err != nil {
return err
}
}
return nil
}
type commsEmailTemplateJoins[Q dialect.Joinable] struct {
typ string
TemplateEmailLogs modAs[Q, commsEmailLogColumns]
}
func (j commsEmailTemplateJoins[Q]) aliasedAs(alias string) commsEmailTemplateJoins[Q] {
return buildCommsEmailTemplateJoins[Q](buildCommsEmailTemplateColumns(alias), j.typ)
}
func buildCommsEmailTemplateJoins[Q dialect.Joinable](cols commsEmailTemplateColumns, typ string) commsEmailTemplateJoins[Q] {
return commsEmailTemplateJoins[Q]{
typ: typ,
TemplateEmailLogs: modAs[Q, commsEmailLogColumns]{
c: CommsEmailLogs.Columns,
f: func(to commsEmailLogColumns) bob.Mod[Q] {
mods := make(mods.QueryMods[Q], 0, 1)
{
mods = append(mods, dialect.Join[Q](typ, CommsEmailLogs.Name().As(to.Alias())).On(
to.TemplateID.EQ(cols.ID),
))
}
return mods
},
},
}
}

View file

@ -43,9 +43,8 @@ type CommsPhonesQuery = *psql.ViewQuery[*CommsPhone, CommsPhoneSlice]
// commsPhoneR is where relationships are stored.
type commsPhoneR struct {
SourceEmailLogs CommsEmailLogSlice // comms.email_log.email_log_source_fkey
DestinationTextLogs CommsTextLogSlice // comms.text_log.text_log_destination_fkey
SourceTextLogs CommsTextLogSlice // comms.text_log.text_log_source_fkey
DestinationTextLogs CommsTextLogSlice // comms.text_log.text_log_destination_fkey
SourceTextLogs CommsTextLogSlice // comms.text_log.text_log_source_fkey
}
func buildCommsPhoneColumns(alias string) commsPhoneColumns {
@ -372,30 +371,6 @@ func (o CommsPhoneSlice) ReloadAll(ctx context.Context, exec bob.Executor) error
return nil
}
// SourceEmailLogs starts a query for related objects on comms.email_log
func (o *CommsPhone) SourceEmailLogs(mods ...bob.Mod[*dialect.SelectQuery]) CommsEmailLogsQuery {
return CommsEmailLogs.Query(append(mods,
sm.Where(CommsEmailLogs.Columns.Source.EQ(psql.Arg(o.E164))),
)...)
}
func (os CommsPhoneSlice) SourceEmailLogs(mods ...bob.Mod[*dialect.SelectQuery]) CommsEmailLogsQuery {
pkE164 := make(pgtypes.Array[string], 0, len(os))
for _, o := range os {
if o == nil {
continue
}
pkE164 = append(pkE164, o.E164)
}
PKArgExpr := psql.Select(sm.Columns(
psql.F("unnest", psql.Cast(psql.Arg(pkE164), "text[]")),
))
return CommsEmailLogs.Query(append(mods,
sm.Where(psql.Group(CommsEmailLogs.Columns.Source).OP("IN", PKArgExpr)),
)...)
}
// DestinationTextLogs starts a query for related objects on comms.text_log
func (o *CommsPhone) DestinationTextLogs(mods ...bob.Mod[*dialect.SelectQuery]) CommsTextLogsQuery {
return CommsTextLogs.Query(append(mods,
@ -444,74 +419,6 @@ func (os CommsPhoneSlice) SourceTextLogs(mods ...bob.Mod[*dialect.SelectQuery])
)...)
}
func insertCommsPhoneSourceEmailLogs0(ctx context.Context, exec bob.Executor, commsEmailLogs1 []*CommsEmailLogSetter, commsPhone0 *CommsPhone) (CommsEmailLogSlice, error) {
for i := range commsEmailLogs1 {
commsEmailLogs1[i].Source = omit.From(commsPhone0.E164)
}
ret, err := CommsEmailLogs.Insert(bob.ToMods(commsEmailLogs1...)).All(ctx, exec)
if err != nil {
return ret, fmt.Errorf("insertCommsPhoneSourceEmailLogs0: %w", err)
}
return ret, nil
}
func attachCommsPhoneSourceEmailLogs0(ctx context.Context, exec bob.Executor, count int, commsEmailLogs1 CommsEmailLogSlice, commsPhone0 *CommsPhone) (CommsEmailLogSlice, error) {
setter := &CommsEmailLogSetter{
Source: omit.From(commsPhone0.E164),
}
err := commsEmailLogs1.UpdateAll(ctx, exec, *setter)
if err != nil {
return nil, fmt.Errorf("attachCommsPhoneSourceEmailLogs0: %w", err)
}
return commsEmailLogs1, nil
}
func (commsPhone0 *CommsPhone) InsertSourceEmailLogs(ctx context.Context, exec bob.Executor, related ...*CommsEmailLogSetter) error {
if len(related) == 0 {
return nil
}
var err error
commsEmailLogs1, err := insertCommsPhoneSourceEmailLogs0(ctx, exec, related, commsPhone0)
if err != nil {
return err
}
commsPhone0.R.SourceEmailLogs = append(commsPhone0.R.SourceEmailLogs, commsEmailLogs1...)
for _, rel := range commsEmailLogs1 {
rel.R.SourcePhone = commsPhone0
}
return nil
}
func (commsPhone0 *CommsPhone) AttachSourceEmailLogs(ctx context.Context, exec bob.Executor, related ...*CommsEmailLog) error {
if len(related) == 0 {
return nil
}
var err error
commsEmailLogs1 := CommsEmailLogSlice(related)
_, err = attachCommsPhoneSourceEmailLogs0(ctx, exec, len(related), commsEmailLogs1, commsPhone0)
if err != nil {
return err
}
commsPhone0.R.SourceEmailLogs = append(commsPhone0.R.SourceEmailLogs, commsEmailLogs1...)
for _, rel := range related {
rel.R.SourcePhone = commsPhone0
}
return nil
}
func insertCommsPhoneDestinationTextLogs0(ctx context.Context, exec bob.Executor, commsTextLogs1 []*CommsTextLogSetter, commsPhone0 *CommsPhone) (CommsTextLogSlice, error) {
for i := range commsTextLogs1 {
commsTextLogs1[i].Destination = omit.From(commsPhone0.E164)
@ -670,20 +577,6 @@ func (o *CommsPhone) Preload(name string, retrieved any) error {
}
switch name {
case "SourceEmailLogs":
rels, ok := retrieved.(CommsEmailLogSlice)
if !ok {
return fmt.Errorf("commsPhone cannot load %T as %q", retrieved, name)
}
o.R.SourceEmailLogs = rels
for _, rel := range rels {
if rel != nil {
rel.R.SourcePhone = o
}
}
return nil
case "DestinationTextLogs":
rels, ok := retrieved.(CommsTextLogSlice)
if !ok {
@ -724,15 +617,11 @@ func buildCommsPhonePreloader() commsPhonePreloader {
}
type commsPhoneThenLoader[Q orm.Loadable] struct {
SourceEmailLogs func(...bob.Mod[*dialect.SelectQuery]) orm.Loader[Q]
DestinationTextLogs func(...bob.Mod[*dialect.SelectQuery]) orm.Loader[Q]
SourceTextLogs func(...bob.Mod[*dialect.SelectQuery]) orm.Loader[Q]
}
func buildCommsPhoneThenLoader[Q orm.Loadable]() commsPhoneThenLoader[Q] {
type SourceEmailLogsLoadInterface interface {
LoadSourceEmailLogs(context.Context, bob.Executor, ...bob.Mod[*dialect.SelectQuery]) error
}
type DestinationTextLogsLoadInterface interface {
LoadDestinationTextLogs(context.Context, bob.Executor, ...bob.Mod[*dialect.SelectQuery]) error
}
@ -741,12 +630,6 @@ func buildCommsPhoneThenLoader[Q orm.Loadable]() commsPhoneThenLoader[Q] {
}
return commsPhoneThenLoader[Q]{
SourceEmailLogs: thenLoadBuilder[Q](
"SourceEmailLogs",
func(ctx context.Context, exec bob.Executor, retrieved SourceEmailLogsLoadInterface, mods ...bob.Mod[*dialect.SelectQuery]) error {
return retrieved.LoadSourceEmailLogs(ctx, exec, mods...)
},
),
DestinationTextLogs: thenLoadBuilder[Q](
"DestinationTextLogs",
func(ctx context.Context, exec bob.Executor, retrieved DestinationTextLogsLoadInterface, mods ...bob.Mod[*dialect.SelectQuery]) error {
@ -762,67 +645,6 @@ func buildCommsPhoneThenLoader[Q orm.Loadable]() commsPhoneThenLoader[Q] {
}
}
// LoadSourceEmailLogs loads the commsPhone's SourceEmailLogs into the .R struct
func (o *CommsPhone) LoadSourceEmailLogs(ctx context.Context, exec bob.Executor, mods ...bob.Mod[*dialect.SelectQuery]) error {
if o == nil {
return nil
}
// Reset the relationship
o.R.SourceEmailLogs = nil
related, err := o.SourceEmailLogs(mods...).All(ctx, exec)
if err != nil {
return err
}
for _, rel := range related {
rel.R.SourcePhone = o
}
o.R.SourceEmailLogs = related
return nil
}
// LoadSourceEmailLogs loads the commsPhone's SourceEmailLogs into the .R struct
func (os CommsPhoneSlice) LoadSourceEmailLogs(ctx context.Context, exec bob.Executor, mods ...bob.Mod[*dialect.SelectQuery]) error {
if len(os) == 0 {
return nil
}
commsEmailLogs, err := os.SourceEmailLogs(mods...).All(ctx, exec)
if err != nil {
return err
}
for _, o := range os {
if o == nil {
continue
}
o.R.SourceEmailLogs = nil
}
for _, o := range os {
if o == nil {
continue
}
for _, rel := range commsEmailLogs {
if !(o.E164 == rel.Source) {
continue
}
rel.R.SourcePhone = o
o.R.SourceEmailLogs = append(o.R.SourceEmailLogs, rel)
}
}
return nil
}
// LoadDestinationTextLogs loads the commsPhone's DestinationTextLogs into the .R struct
func (o *CommsPhone) LoadDestinationTextLogs(ctx context.Context, exec bob.Executor, mods ...bob.Mod[*dialect.SelectQuery]) error {
if o == nil {
@ -947,7 +769,6 @@ func (os CommsPhoneSlice) LoadSourceTextLogs(ctx context.Context, exec bob.Execu
// commsPhoneC is where relationship counts are stored.
type commsPhoneC struct {
SourceEmailLogs *int64
DestinationTextLogs *int64
SourceTextLogs *int64
}
@ -959,8 +780,6 @@ func (o *CommsPhone) PreloadCount(name string, count int64) error {
}
switch name {
case "SourceEmailLogs":
o.C.SourceEmailLogs = &count
case "DestinationTextLogs":
o.C.DestinationTextLogs = &count
case "SourceTextLogs":
@ -970,30 +789,12 @@ func (o *CommsPhone) PreloadCount(name string, count int64) error {
}
type commsPhoneCountPreloader struct {
SourceEmailLogs func(...bob.Mod[*dialect.SelectQuery]) psql.Preloader
DestinationTextLogs func(...bob.Mod[*dialect.SelectQuery]) psql.Preloader
SourceTextLogs func(...bob.Mod[*dialect.SelectQuery]) psql.Preloader
}
func buildCommsPhoneCountPreloader() commsPhoneCountPreloader {
return commsPhoneCountPreloader{
SourceEmailLogs: func(mods ...bob.Mod[*dialect.SelectQuery]) psql.Preloader {
return countPreloader[*CommsPhone]("SourceEmailLogs", func(parent string) bob.Expression {
// Build a correlated subquery: (SELECT COUNT(*) FROM related WHERE fk = parent.pk)
if parent == "" {
parent = CommsPhones.Alias()
}
subqueryMods := []bob.Mod[*dialect.SelectQuery]{
sm.Columns(psql.Raw("count(*)")),
sm.From(CommsEmailLogs.Name()),
sm.Where(psql.Quote(CommsEmailLogs.Alias(), "source").EQ(psql.Quote(parent, "e164"))),
}
subqueryMods = append(subqueryMods, mods...)
return psql.Group(psql.Select(subqueryMods...).Expression)
})
},
DestinationTextLogs: func(mods ...bob.Mod[*dialect.SelectQuery]) psql.Preloader {
return countPreloader[*CommsPhone]("DestinationTextLogs", func(parent string) bob.Expression {
// Build a correlated subquery: (SELECT COUNT(*) FROM related WHERE fk = parent.pk)
@ -1032,15 +833,11 @@ func buildCommsPhoneCountPreloader() commsPhoneCountPreloader {
}
type commsPhoneCountThenLoader[Q orm.Loadable] struct {
SourceEmailLogs func(...bob.Mod[*dialect.SelectQuery]) orm.Loader[Q]
DestinationTextLogs func(...bob.Mod[*dialect.SelectQuery]) orm.Loader[Q]
SourceTextLogs func(...bob.Mod[*dialect.SelectQuery]) orm.Loader[Q]
}
func buildCommsPhoneCountThenLoader[Q orm.Loadable]() commsPhoneCountThenLoader[Q] {
type SourceEmailLogsCountInterface interface {
LoadCountSourceEmailLogs(context.Context, bob.Executor, ...bob.Mod[*dialect.SelectQuery]) error
}
type DestinationTextLogsCountInterface interface {
LoadCountDestinationTextLogs(context.Context, bob.Executor, ...bob.Mod[*dialect.SelectQuery]) error
}
@ -1049,12 +846,6 @@ func buildCommsPhoneCountThenLoader[Q orm.Loadable]() commsPhoneCountThenLoader[
}
return commsPhoneCountThenLoader[Q]{
SourceEmailLogs: countThenLoadBuilder[Q](
"SourceEmailLogs",
func(ctx context.Context, exec bob.Executor, retrieved SourceEmailLogsCountInterface, mods ...bob.Mod[*dialect.SelectQuery]) error {
return retrieved.LoadCountSourceEmailLogs(ctx, exec, mods...)
},
),
DestinationTextLogs: countThenLoadBuilder[Q](
"DestinationTextLogs",
func(ctx context.Context, exec bob.Executor, retrieved DestinationTextLogsCountInterface, mods ...bob.Mod[*dialect.SelectQuery]) error {
@ -1070,36 +861,6 @@ func buildCommsPhoneCountThenLoader[Q orm.Loadable]() commsPhoneCountThenLoader[
}
}
// LoadCountSourceEmailLogs loads the count of SourceEmailLogs into the C struct
func (o *CommsPhone) LoadCountSourceEmailLogs(ctx context.Context, exec bob.Executor, mods ...bob.Mod[*dialect.SelectQuery]) error {
if o == nil {
return nil
}
count, err := o.SourceEmailLogs(mods...).Count(ctx, exec)
if err != nil {
return err
}
o.C.SourceEmailLogs = &count
return nil
}
// LoadCountSourceEmailLogs loads the count of SourceEmailLogs for a slice
func (os CommsPhoneSlice) LoadCountSourceEmailLogs(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.LoadCountSourceEmailLogs(ctx, exec, mods...); err != nil {
return err
}
}
return nil
}
// LoadCountDestinationTextLogs loads the count of DestinationTextLogs into the C struct
func (o *CommsPhone) LoadCountDestinationTextLogs(ctx context.Context, exec bob.Executor, mods ...bob.Mod[*dialect.SelectQuery]) error {
if o == nil {
@ -1162,7 +923,6 @@ func (os CommsPhoneSlice) LoadCountSourceTextLogs(ctx context.Context, exec bob.
type commsPhoneJoins[Q dialect.Joinable] struct {
typ string
SourceEmailLogs modAs[Q, commsEmailLogColumns]
DestinationTextLogs modAs[Q, commsTextLogColumns]
SourceTextLogs modAs[Q, commsTextLogColumns]
}
@ -1174,20 +934,6 @@ func (j commsPhoneJoins[Q]) aliasedAs(alias string) commsPhoneJoins[Q] {
func buildCommsPhoneJoins[Q dialect.Joinable](cols commsPhoneColumns, typ string) commsPhoneJoins[Q] {
return commsPhoneJoins[Q]{
typ: typ,
SourceEmailLogs: modAs[Q, commsEmailLogColumns]{
c: CommsEmailLogs.Columns,
f: func(to commsEmailLogColumns) bob.Mod[Q] {
mods := make(mods.QueryMods[Q], 0, 1)
{
mods = append(mods, dialect.Join[Q](typ, CommsEmailLogs.Name().As(to.Alias())).On(
to.Source.EQ(cols.E164),
))
}
return mods
},
},
DestinationTextLogs: modAs[Q, commsTextLogColumns]{
c: CommsTextLogs.Columns,
f: func(to commsTextLogColumns) bob.Mod[Q] {

View file

@ -12,6 +12,7 @@ import (
"github.com/Gleipnir-Technology/nidus-sync/auth"
"github.com/Gleipnir-Technology/nidus-sync/background"
"github.com/Gleipnir-Technology/nidus-sync/comms/email"
"github.com/Gleipnir-Technology/nidus-sync/config"
"github.com/Gleipnir-Technology/nidus-sync/db"
"github.com/Gleipnir-Technology/nidus-sync/public-report"
@ -39,6 +40,12 @@ func main() {
os.Exit(2)
}
err = email.LoadTemplates()
if err != nil {
log.Error().Err(err).Msg("Failed to load email templates")
os.Exit(3)
}
router_logger := log.With().Logger()
r := chi.NewRouter()

View file

@ -1,17 +1,18 @@
package publicreport
import (
"fmt"
"net/http"
"github.com/Gleipnir-Technology/nidus-sync/comms"
//"github.com/Gleipnir-Technology/nidus-sync/comms/email"
"github.com/go-chi/chi/v5"
)
func getEmailInitial(w http.ResponseWriter, r *http.Request) {
email := chi.URLParam(r, "email")
comms.RenderEmailInitial(w, email)
}
func getEmailReportSubscriptionConfirmation(w http.ResponseWriter, r *http.Request) {
report_id := chi.URLParam(r, "report_id")
comms.RenderEmailReportConfirmation(w, report_id)
func getEmailByCode(w http.ResponseWriter, r *http.Request) {
code := chi.URLParam(r, "code")
if code == "" {
http.Error(w, "You must specify a code", http.StatusBadRequest)
return
}
fmt.Fprintf(w, "Pretend email contet for %s", code)
}

View file

@ -258,7 +258,7 @@ func postRegisterNotifications(w http.ResponseWriter, r *http.Request) {
return
}
if email != "" {
background.ReportSubscriptionConfirmationEmail(email)
background.ReportSubscriptionConfirmationEmail(email, report_id)
}
if phone_str != "" {
background.ReportSubscriptionConfirmationText(*phone, report_id)

View file

@ -10,8 +10,7 @@ func Router() chi.Router {
r.Get("/", getRoot)
r.Get("/privacy", getPrivacy)
r.Get("/robots.txt", getRobots)
r.Get("/email/initial", getEmailInitial)
r.Get("/email/report/{report_id}/subscription-confirmation", getEmailReportSubscriptionConfirmation)
r.Get("/email", getEmailByCode)
r.Get("/image/{uuid}", getImageByUUID)
r.Get("/nuisance", getNuisance)
r.Post("/nuisance-submit", postNuisance)