Move comms work to background goroutine

This is a sort of random checkpoint of work
 * add schema for tracking messages sent to DB
 * add terms of service and privacy policy for RCS compliance
 * standardize some things about background workers
 * update some missing stuff from generated DB code
This commit is contained in:
Eli Ribble 2026-01-20 17:10:22 +00:00
parent 8f44e57c72
commit 842e6cff43
No known key found for this signature in database
47 changed files with 7361 additions and 179 deletions

View file

@ -74,7 +74,7 @@ func apiAudioContentPost(w http.ResponseWriter, r *http.Request, u *models.User)
http.Error(w, "failed to write content file", http.StatusInternalServerError)
}
queue.EnqueueAudioJob(queue.AudioJob{AudioUUID: audioUUID})
queue.EnqueueAudioJob(queue.JobAudio{AudioUUID: audioUUID})
w.WriteHeader(http.StatusOK)
}

101
background/audio.go Normal file
View file

@ -0,0 +1,101 @@
package background
import (
"context"
"errors"
"fmt"
"os"
"os/exec"
"github.com/Gleipnir-Technology/nidus-sync/db"
"github.com/Gleipnir-Technology/nidus-sync/queue"
"github.com/Gleipnir-Technology/nidus-sync/userfile"
"github.com/google/uuid"
"github.com/rs/zerolog/log"
)
// StartAudioWorker initializes the audio job channel and starts the worker goroutine.
func StartWorkerAudio(ctx context.Context, audioJobChannel chan queue.JobAudio) {
go func() {
for {
select {
case <-ctx.Done():
log.Info().Msg("Audio worker shutting down.")
return
case job := <-audioJobChannel:
log.Info().Str("uuid", job.AudioUUID.String()).Msg("Processing audio job")
err := processAudioFile(job.AudioUUID)
if err != nil {
log.Error().Err(err).Str("uuid", job.AudioUUID.String()).Msg("Error processing audio file")
}
}
}
}()
}
func normalizeAudio(audioUUID uuid.UUID) error {
source := userfile.AudioFileContentPathRaw(audioUUID.String())
_, err := os.Stat(source)
if errors.Is(err, os.ErrNotExist) {
log.Warn().Str("source", source).Msg("file doesn't exist, skipping normalization")
return nil
}
log.Info().Str("sourcce", source).Msg("Normalizing")
destination := userfile.AudioFileContentPathNormalized(audioUUID.String())
// Use "ffmpeg" directly, assuming it's in the system PATH
cmd := exec.Command("ffmpeg", "-i", source, "-filter:a", "loudnorm", destination)
out, err := cmd.CombinedOutput()
if err != nil {
log.Printf("FFmpeg output for normalization: %s", out)
return fmt.Errorf("ffmpeg normalization failed: %v", err)
}
err = db.NoteAudioNormalized(audioUUID.String())
if err != nil {
return fmt.Errorf("failed to update database for normalized audio %s: %v", audioUUID, err)
}
log.Info().Str("destination", destination).Msg("Normalized audio")
return nil
}
func processAudioFile(audioUUID uuid.UUID) error {
// Normalize audio
err := normalizeAudio(audioUUID)
if err != nil {
return fmt.Errorf("failed to normalize audio %s: %v", audioUUID, err)
}
// Transcode to OGG
err = transcodeToOgg(audioUUID)
if err != nil {
return fmt.Errorf("failed to transcode audio %s to OGG: %v", audioUUID, err)
}
queue.EnqueueLabelStudioJob(queue.LabelStudioJob{
UUID: audioUUID,
})
return nil
}
func transcodeToOgg(audioUUID uuid.UUID) error {
source := userfile.AudioFileContentPathNormalized(audioUUID.String())
_, err := os.Stat(source)
if errors.Is(err, os.ErrNotExist) {
log.Warn().Str("source", source).Msg("file doesn't exist, skipping OGG transcoding")
return nil
}
log.Info().Str("source", source).Msg("Transcoding to ogg")
destination := userfile.AudioFileContentPathOgg(audioUUID.String())
// Use "ffmpeg" directly, assuming it's in the system PATH
cmd := exec.Command("ffmpeg", "-i", source, "-vn", "-acodec", "libvorbis", destination)
out, err := cmd.CombinedOutput()
if err != nil {
log.Error().Err(err).Bytes("out", out).Msg("FFmpeg output for OGG transcoding")
return fmt.Errorf("ffmpeg OGG transcoding failed: %v", err)
}
err = db.NoteAudioTranscodedToOgg(audioUUID.String())
if err != nil {
return fmt.Errorf("failed to update database for OGG transcoded audio %s: %v", audioUUID, err)
}
log.Info().Str("destination", destination).Msg("Transcoded audio")
return nil
}

52
background/comms.go Normal file
View file

@ -0,0 +1,52 @@
package background
import (
"context"
"github.com/Gleipnir-Technology/nidus-sync/queue"
"github.com/rs/zerolog/log"
)
func StartWorkerEmail(ctx context.Context, channel chan queue.JobEmail) {
go func() {
for {
select {
case <-ctx.Done():
log.Info().Msg("Email worker shutting down.")
return
case job := <-channel:
err := processJobEmail(job)
if err != nil {
log.Error().Err(err).Str("dest", job.Destination).Str("type", string(job.Type)).Msg("Error processing audio file")
}
}
}
}()
}
func StartWorkerSMS(ctx context.Context, channel chan queue.JobSMS) {
go func() {
for {
select {
case <-ctx.Done():
log.Info().Msg("Email worker shutting down.")
return
case job := <-channel:
err := processJobSMS(job)
if err != nil {
log.Error().Err(err).Str("dest", job.Destination).Str("type", string(job.Type)).Msg("Error processing audio file")
}
}
}
}()
}
func processJobEmail(job queue.JobEmail) error {
log.Info().Str("dest", job.Destination).Str("type", string(job.Type)).Msg("Pretend doing email job")
return nil
}
func processJobSMS(job queue.JobSMS) error {
log.Info().Str("dest", job.Destination).Str("type", string(job.Type)).Msg("Pretend doing email job")
return nil
}

View file

@ -131,15 +131,15 @@ func renderOrError(w http.ResponseWriter, template *builtTemplate, context inter
buf.WriteTo(w)
}
func sendEmail(email emailRequest) (response emailResponse, err error) {
url := "https://api.forwardemail.net/v1/emails"
var FORWARDEMAIL_API = "https://api.forwardemail.net/v1/emails"
func sendEmail(email emailRequest) (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", url, bytes.NewReader(payload))
req, _ := http.NewRequest("POST", FORWARDEMAIL_API, bytes.NewReader(payload))
req.SetBasicAuth(config.ForwardEmailAPIToken, "")
req.Header.Add("Content-Type", "application/json")

View file

@ -13,6 +13,7 @@ no_tests: true
psql:
schemas:
- "arcgis"
- "comms"
- "import"
- "public"
- "publicreport"

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 CommsEmailErrors = &commsEmailErrors{
ErrUniqueEmailPkey: &UniqueConstraintError{
schema: "comms",
table: "email",
columns: []string{"address"},
s: "email_pkey",
},
}
type commsEmailErrors struct {
ErrUniqueEmailPkey *UniqueConstraintError
}

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 CommsEmailLogErrors = &commsEmailLogErrors{
ErrUniqueEmailLogPkey: &UniqueConstraintError{
schema: "comms",
table: "email_log",
columns: []string{"destination", "source", "type"},
s: "email_log_pkey",
},
}
type commsEmailLogErrors struct {
ErrUniqueEmailLogPkey *UniqueConstraintError
}

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 CommsPhoneErrors = &commsPhoneErrors{
ErrUniquePhonePkey: &UniqueConstraintError{
schema: "comms",
table: "phone",
columns: []string{"e164"},
s: "phone_pkey",
},
}
type commsPhoneErrors struct {
ErrUniquePhonePkey *UniqueConstraintError
}

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 CommsSMSLogErrors = &commsSMSLogErrors{
ErrUniqueSmsLogPkey: &UniqueConstraintError{
schema: "comms",
table: "sms_log",
columns: []string{"destination", "source", "type"},
s: "sms_log_pkey",
},
}
type commsSMSLogErrors struct {
ErrUniqueSmsLogPkey *UniqueConstraintError
}

View file

@ -0,0 +1,112 @@
// 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 CommsEmails = Table[
commsEmailColumns,
commsEmailIndexes,
commsEmailForeignKeys,
commsEmailUniques,
commsEmailChecks,
]{
Schema: "comms",
Name: "email",
Columns: commsEmailColumns{
Address: column{
Name: "address",
DBType: "text",
Default: "",
Comment: "",
Nullable: false,
Generated: false,
AutoIncr: false,
},
Confirmed: column{
Name: "confirmed",
DBType: "boolean",
Default: "",
Comment: "",
Nullable: false,
Generated: false,
AutoIncr: false,
},
IsSubscribed: column{
Name: "is_subscribed",
DBType: "boolean",
Default: "",
Comment: "",
Nullable: false,
Generated: false,
AutoIncr: false,
},
},
Indexes: commsEmailIndexes{
EmailPkey: index{
Type: "btree",
Name: "email_pkey",
Columns: []indexColumn{
{
Name: "address",
Desc: null.FromCond(false, true),
IsExpression: false,
},
},
Unique: true,
Comment: "",
NullsFirst: []bool{false},
NullsDistinct: false,
Where: "",
Include: []string{},
},
},
PrimaryKey: &constraint{
Name: "email_pkey",
Columns: []string{"address"},
Comment: "",
},
Comment: "",
}
type commsEmailColumns struct {
Address column
Confirmed column
IsSubscribed column
}
func (c commsEmailColumns) AsSlice() []column {
return []column{
c.Address, c.Confirmed, c.IsSubscribed,
}
}
type commsEmailIndexes struct {
EmailPkey index
}
func (i commsEmailIndexes) AsSlice() []index {
return []index{
i.EmailPkey,
}
}
type commsEmailForeignKeys struct{}
func (f commsEmailForeignKeys) AsSlice() []foreignKey {
return []foreignKey{}
}
type commsEmailUniques struct{}
func (u commsEmailUniques) AsSlice() []constraint {
return []constraint{}
}
type commsEmailChecks struct{}
func (c commsEmailChecks) AsSlice() []check {
return []check{}
}

View file

@ -0,0 +1,157 @@
// 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 CommsEmailLogs = Table[
commsEmailLogColumns,
commsEmailLogIndexes,
commsEmailLogForeignKeys,
commsEmailLogUniques,
commsEmailLogChecks,
]{
Schema: "comms",
Name: "email_log",
Columns: commsEmailLogColumns{
Created: column{
Name: "created",
DBType: "timestamp without time zone",
Default: "",
Comment: "",
Nullable: false,
Generated: false,
AutoIncr: false,
},
Destination: column{
Name: "destination",
DBType: "text",
Default: "",
Comment: "",
Nullable: false,
Generated: false,
AutoIncr: false,
},
Source: column{
Name: "source",
DBType: "text",
Default: "",
Comment: "",
Nullable: false,
Generated: false,
AutoIncr: false,
},
Type: column{
Name: "type",
DBType: "comms.emailmessagetype",
Default: "",
Comment: "",
Nullable: false,
Generated: false,
AutoIncr: false,
},
},
Indexes: commsEmailLogIndexes{
EmailLogPkey: index{
Type: "btree",
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",
Desc: null.FromCond(false, true),
IsExpression: false,
},
},
Unique: true,
Comment: "",
NullsFirst: []bool{false, false, false},
NullsDistinct: false,
Where: "",
Include: []string{},
},
},
PrimaryKey: &constraint{
Name: "email_log_pkey",
Columns: []string{"destination", "source", "type"},
Comment: "",
},
ForeignKeys: commsEmailLogForeignKeys{
CommsEmailLogEmailLogDestinationFkey: foreignKey{
constraint: constraint{
Name: "comms.email_log.email_log_destination_fkey",
Columns: []string{"destination"},
Comment: "",
},
ForeignTable: "comms.email",
ForeignColumns: []string{"address"},
},
CommsEmailLogEmailLogSourceFkey: foreignKey{
constraint: constraint{
Name: "comms.email_log.email_log_source_fkey",
Columns: []string{"source"},
Comment: "",
},
ForeignTable: "comms.phone",
ForeignColumns: []string{"e164"},
},
},
Comment: "",
}
type commsEmailLogColumns struct {
Created column
Destination column
Source column
Type column
}
func (c commsEmailLogColumns) AsSlice() []column {
return []column{
c.Created, c.Destination, c.Source, c.Type,
}
}
type commsEmailLogIndexes struct {
EmailLogPkey index
}
func (i commsEmailLogIndexes) AsSlice() []index {
return []index{
i.EmailLogPkey,
}
}
type commsEmailLogForeignKeys struct {
CommsEmailLogEmailLogDestinationFkey foreignKey
CommsEmailLogEmailLogSourceFkey foreignKey
}
func (f commsEmailLogForeignKeys) AsSlice() []foreignKey {
return []foreignKey{
f.CommsEmailLogEmailLogDestinationFkey, f.CommsEmailLogEmailLogSourceFkey,
}
}
type commsEmailLogUniques struct{}
func (u commsEmailLogUniques) AsSlice() []constraint {
return []constraint{}
}
type commsEmailLogChecks struct{}
func (c commsEmailLogChecks) AsSlice() []check {
return []check{}
}

View file

@ -0,0 +1,102 @@
// 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 CommsPhones = Table[
commsPhoneColumns,
commsPhoneIndexes,
commsPhoneForeignKeys,
commsPhoneUniques,
commsPhoneChecks,
]{
Schema: "comms",
Name: "phone",
Columns: commsPhoneColumns{
E164: column{
Name: "e164",
DBType: "text",
Default: "",
Comment: "",
Nullable: false,
Generated: false,
AutoIncr: false,
},
IsSubscribed: column{
Name: "is_subscribed",
DBType: "boolean",
Default: "",
Comment: "",
Nullable: false,
Generated: false,
AutoIncr: false,
},
},
Indexes: commsPhoneIndexes{
PhonePkey: index{
Type: "btree",
Name: "phone_pkey",
Columns: []indexColumn{
{
Name: "e164",
Desc: null.FromCond(false, true),
IsExpression: false,
},
},
Unique: true,
Comment: "",
NullsFirst: []bool{false},
NullsDistinct: false,
Where: "",
Include: []string{},
},
},
PrimaryKey: &constraint{
Name: "phone_pkey",
Columns: []string{"e164"},
Comment: "",
},
Comment: "",
}
type commsPhoneColumns struct {
E164 column
IsSubscribed column
}
func (c commsPhoneColumns) AsSlice() []column {
return []column{
c.E164, c.IsSubscribed,
}
}
type commsPhoneIndexes struct {
PhonePkey index
}
func (i commsPhoneIndexes) AsSlice() []index {
return []index{
i.PhonePkey,
}
}
type commsPhoneForeignKeys struct{}
func (f commsPhoneForeignKeys) AsSlice() []foreignKey {
return []foreignKey{}
}
type commsPhoneUniques struct{}
func (u commsPhoneUniques) AsSlice() []constraint {
return []constraint{}
}
type commsPhoneChecks struct{}
func (c commsPhoneChecks) AsSlice() []check {
return []check{}
}

View file

@ -0,0 +1,157 @@
// 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 CommsSMSLogs = Table[
commsSMSLogColumns,
commsSMSLogIndexes,
commsSMSLogForeignKeys,
commsSMSLogUniques,
commsSMSLogChecks,
]{
Schema: "comms",
Name: "sms_log",
Columns: commsSMSLogColumns{
Created: column{
Name: "created",
DBType: "timestamp without time zone",
Default: "",
Comment: "",
Nullable: false,
Generated: false,
AutoIncr: false,
},
Destination: column{
Name: "destination",
DBType: "text",
Default: "",
Comment: "",
Nullable: false,
Generated: false,
AutoIncr: false,
},
Source: column{
Name: "source",
DBType: "text",
Default: "",
Comment: "",
Nullable: false,
Generated: false,
AutoIncr: false,
},
Type: column{
Name: "type",
DBType: "comms.smsmessagetype",
Default: "",
Comment: "",
Nullable: false,
Generated: false,
AutoIncr: false,
},
},
Indexes: commsSMSLogIndexes{
SMSLogPkey: index{
Type: "btree",
Name: "sms_log_pkey",
Columns: []indexColumn{
{
Name: "destination",
Desc: null.FromCond(false, true),
IsExpression: false,
},
{
Name: "source",
Desc: null.FromCond(false, true),
IsExpression: false,
},
{
Name: "type",
Desc: null.FromCond(false, true),
IsExpression: false,
},
},
Unique: true,
Comment: "",
NullsFirst: []bool{false, false, false},
NullsDistinct: false,
Where: "",
Include: []string{},
},
},
PrimaryKey: &constraint{
Name: "sms_log_pkey",
Columns: []string{"destination", "source", "type"},
Comment: "",
},
ForeignKeys: commsSMSLogForeignKeys{
CommsSMSLogSMSLogDestinationFkey: foreignKey{
constraint: constraint{
Name: "comms.sms_log.sms_log_destination_fkey",
Columns: []string{"destination"},
Comment: "",
},
ForeignTable: "comms.phone",
ForeignColumns: []string{"e164"},
},
CommsSMSLogSMSLogSourceFkey: foreignKey{
constraint: constraint{
Name: "comms.sms_log.sms_log_source_fkey",
Columns: []string{"source"},
Comment: "",
},
ForeignTable: "comms.phone",
ForeignColumns: []string{"e164"},
},
},
Comment: "",
}
type commsSMSLogColumns struct {
Created column
Destination column
Source column
Type column
}
func (c commsSMSLogColumns) AsSlice() []column {
return []column{
c.Created, c.Destination, c.Source, c.Type,
}
}
type commsSMSLogIndexes struct {
SMSLogPkey index
}
func (i commsSMSLogIndexes) AsSlice() []index {
return []index{
i.SMSLogPkey,
}
}
type commsSMSLogForeignKeys struct {
CommsSMSLogSMSLogDestinationFkey foreignKey
CommsSMSLogSMSLogSourceFkey foreignKey
}
func (f commsSMSLogForeignKeys) AsSlice() []foreignKey {
return []foreignKey{
f.CommsSMSLogSMSLogDestinationFkey, f.CommsSMSLogSMSLogSourceFkey,
}
}
type commsSMSLogUniques struct{}
func (u commsSMSLogUniques) AsSlice() []constraint {
return []constraint{}
}
type commsSMSLogChecks struct{}
func (c commsSMSLogChecks) AsSlice() []check {
return []check{}
}

View file

@ -42,6 +42,15 @@ var PublicreportImages = Table[
Generated: false,
AutoIncr: false,
},
Location: column{
Name: "location",
DBType: "geography",
Default: "NULL",
Comment: "",
Nullable: true,
Generated: false,
AutoIncr: false,
},
ResolutionX: column{
Name: "resolution_x",
DBType: "integer",
@ -120,6 +129,7 @@ type publicreportImageColumns struct {
ID column
ContentType column
Created column
Location column
ResolutionX column
ResolutionY column
StorageUUID column
@ -129,7 +139,7 @@ type publicreportImageColumns struct {
func (c publicreportImageColumns) AsSlice() []column {
return []column{
c.ID, c.ContentType, c.Created, c.ResolutionX, c.ResolutionY, c.StorageUUID, c.StorageSize, c.UploadedFilename,
c.ID, c.ContentType, c.Created, c.Location, c.ResolutionX, c.ResolutionY, c.StorageUUID, c.StorageSize, c.UploadedFilename,
}
}

View file

@ -193,6 +193,158 @@ func (e *Audiodatatype) Scan(value any) error {
return nil
}
// Enum values for CommsEmailmessagetype
const (
CommsEmailmessagetypeReportSubscriptionConfirmation CommsEmailmessagetype = "report-subscription-confirmation"
CommsEmailmessagetypeReportStatusScheduled CommsEmailmessagetype = "report-status-scheduled"
CommsEmailmessagetypeReportStatusComplete CommsEmailmessagetype = "report-status-complete"
)
func AllCommsEmailmessagetype() []CommsEmailmessagetype {
return []CommsEmailmessagetype{
CommsEmailmessagetypeReportSubscriptionConfirmation,
CommsEmailmessagetypeReportStatusScheduled,
CommsEmailmessagetypeReportStatusComplete,
}
}
type CommsEmailmessagetype string
func (e CommsEmailmessagetype) String() string {
return string(e)
}
func (e CommsEmailmessagetype) Valid() bool {
switch e {
case CommsEmailmessagetypeReportSubscriptionConfirmation,
CommsEmailmessagetypeReportStatusScheduled,
CommsEmailmessagetypeReportStatusComplete:
return true
default:
return false
}
}
// useful when testing in other packages
func (e CommsEmailmessagetype) All() []CommsEmailmessagetype {
return AllCommsEmailmessagetype()
}
func (e CommsEmailmessagetype) MarshalText() ([]byte, error) {
return []byte(e), nil
}
func (e *CommsEmailmessagetype) UnmarshalText(text []byte) error {
return e.Scan(text)
}
func (e CommsEmailmessagetype) MarshalBinary() ([]byte, error) {
return []byte(e), nil
}
func (e *CommsEmailmessagetype) UnmarshalBinary(data []byte) error {
return e.Scan(data)
}
func (e CommsEmailmessagetype) Value() (driver.Value, error) {
return string(e), nil
}
func (e *CommsEmailmessagetype) Scan(value any) error {
switch x := value.(type) {
case string:
*e = CommsEmailmessagetype(x)
case []byte:
*e = CommsEmailmessagetype(x)
case nil:
return fmt.Errorf("cannot nil into CommsEmailmessagetype")
default:
return fmt.Errorf("cannot scan type %T: %v", value, value)
}
if !e.Valid() {
return fmt.Errorf("invalid CommsEmailmessagetype value: %s", *e)
}
return nil
}
// Enum values for CommsSmsmessagetype
const (
CommsSmsmessagetypeReportSubscriptionConfirmation CommsSmsmessagetype = "report-subscription-confirmation"
CommsSmsmessagetypeReportStatusScheduled CommsSmsmessagetype = "report-status-scheduled"
CommsSmsmessagetypeReportStatusComplete CommsSmsmessagetype = "report-status-complete"
)
func AllCommsSmsmessagetype() []CommsSmsmessagetype {
return []CommsSmsmessagetype{
CommsSmsmessagetypeReportSubscriptionConfirmation,
CommsSmsmessagetypeReportStatusScheduled,
CommsSmsmessagetypeReportStatusComplete,
}
}
type CommsSmsmessagetype string
func (e CommsSmsmessagetype) String() string {
return string(e)
}
func (e CommsSmsmessagetype) Valid() bool {
switch e {
case CommsSmsmessagetypeReportSubscriptionConfirmation,
CommsSmsmessagetypeReportStatusScheduled,
CommsSmsmessagetypeReportStatusComplete:
return true
default:
return false
}
}
// useful when testing in other packages
func (e CommsSmsmessagetype) All() []CommsSmsmessagetype {
return AllCommsSmsmessagetype()
}
func (e CommsSmsmessagetype) MarshalText() ([]byte, error) {
return []byte(e), nil
}
func (e *CommsSmsmessagetype) UnmarshalText(text []byte) error {
return e.Scan(text)
}
func (e CommsSmsmessagetype) MarshalBinary() ([]byte, error) {
return []byte(e), nil
}
func (e *CommsSmsmessagetype) UnmarshalBinary(data []byte) error {
return e.Scan(data)
}
func (e CommsSmsmessagetype) Value() (driver.Value, error) {
return string(e), nil
}
func (e *CommsSmsmessagetype) Scan(value any) error {
switch x := value.(type) {
case string:
*e = CommsSmsmessagetype(x)
case []byte:
*e = CommsSmsmessagetype(x)
case nil:
return fmt.Errorf("cannot nil into CommsSmsmessagetype")
default:
return fmt.Errorf("cannot scan type %T: %v", value, value)
}
if !e.Valid() {
return fmt.Errorf("invalid CommsSmsmessagetype value: %s", *e)
}
return nil
}
// Enum values for H3aggregationtype
const (
H3aggregationtypeMosquitosource H3aggregationtype = "MosquitoSource"

View file

@ -17,6 +17,26 @@ 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_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")
// Relationship Contexts for comms.phone
commsPhoneWithParentsCascadingCtx = newContextual[bool]("commsPhoneWithParentsCascading")
commsPhoneRelSourceEmailLogsCtx = newContextual[bool]("comms.email_log.comms.phone.comms.email_log.email_log_source_fkey")
commsPhoneRelDestinationSMSLogsCtx = newContextual[bool]("comms.phone.comms.sms_log.comms.sms_log.sms_log_destination_fkey")
commsPhoneRelSourceSMSLogsCtx = newContextual[bool]("comms.phone.comms.sms_log.comms.sms_log.sms_log_source_fkey")
// Relationship Contexts for comms.sms_log
commsSMSLogWithParentsCascadingCtx = newContextual[bool]("commsSMSLogWithParentsCascading")
commsSMSLogRelDestinationPhoneCtx = newContextual[bool]("comms.phone.comms.sms_log.comms.sms_log.sms_log_destination_fkey")
commsSMSLogRelSourcePhoneCtx = newContextual[bool]("comms.phone.comms.sms_log.comms.sms_log.sms_log_source_fkey")
// Relationship Contexts for fieldseeker.containerrelate
fieldseekerContainerrelateWithParentsCascadingCtx = newContextual[bool]("fieldseekerContainerrelateWithParentsCascading")
fieldseekerContainerrelateRelOrganizationCtx = newContextual[bool]("fieldseeker.containerrelate.organization.fieldseeker.containerrelate.containerrelate_organization_id_fkey")

View file

@ -20,6 +20,10 @@ import (
type Factory struct {
baseArcgisUserMods ArcgisUserModSlice
baseArcgisUserPrivilegeMods ArcgisUserPrivilegeModSlice
baseCommsEmailMods CommsEmailModSlice
baseCommsEmailLogMods CommsEmailLogModSlice
baseCommsPhoneMods CommsPhoneModSlice
baseCommsSMSLogMods CommsSMSLogModSlice
baseFieldseekerContainerrelateMods FieldseekerContainerrelateModSlice
baseFieldseekerFieldscoutinglogMods FieldseekerFieldscoutinglogModSlice
baseFieldseekerHabitatrelateMods FieldseekerHabitatrelateModSlice
@ -156,6 +160,143 @@ 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) NewCommsEmailWithContext(ctx context.Context, mods ...CommsEmailMod) *CommsEmailTemplate {
o := &CommsEmailTemplate{f: f}
if f != nil {
f.baseCommsEmailMods.Apply(ctx, o)
}
CommsEmailModSlice(mods).Apply(ctx, o)
return o
}
func (f *Factory) FromExistingCommsEmail(m *models.CommsEmail) *CommsEmailTemplate {
o := &CommsEmailTemplate{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 }
ctx := context.Background()
if len(m.R.DestinationEmailLogs) > 0 {
CommsEmailMods.AddExistingDestinationEmailLogs(m.R.DestinationEmailLogs...).Apply(ctx, o)
}
return o
}
func (f *Factory) NewCommsEmailLog(mods ...CommsEmailLogMod) *CommsEmailLogTemplate {
return f.NewCommsEmailLogWithContext(context.Background(), mods...)
}
func (f *Factory) NewCommsEmailLogWithContext(ctx context.Context, mods ...CommsEmailLogMod) *CommsEmailLogTemplate {
o := &CommsEmailLogTemplate{f: f}
if f != nil {
f.baseCommsEmailLogMods.Apply(ctx, o)
}
CommsEmailLogModSlice(mods).Apply(ctx, o)
return o
}
func (f *Factory) FromExistingCommsEmailLog(m *models.CommsEmailLog) *CommsEmailLogTemplate {
o := &CommsEmailLogTemplate{f: f, alreadyPersisted: true}
o.Created = func() time.Time { return m.Created }
o.Destination = func() string { return m.Destination }
o.Source = func() string { return m.Source }
o.Type = func() enums.CommsEmailmessagetype { return m.Type }
ctx := context.Background()
if m.R.DestinationEmail != nil {
CommsEmailLogMods.WithExistingDestinationEmail(m.R.DestinationEmail).Apply(ctx, o)
}
if m.R.SourcePhone != nil {
CommsEmailLogMods.WithExistingSourcePhone(m.R.SourcePhone).Apply(ctx, o)
}
return o
}
func (f *Factory) NewCommsPhone(mods ...CommsPhoneMod) *CommsPhoneTemplate {
return f.NewCommsPhoneWithContext(context.Background(), mods...)
}
func (f *Factory) NewCommsPhoneWithContext(ctx context.Context, mods ...CommsPhoneMod) *CommsPhoneTemplate {
o := &CommsPhoneTemplate{f: f}
if f != nil {
f.baseCommsPhoneMods.Apply(ctx, o)
}
CommsPhoneModSlice(mods).Apply(ctx, o)
return o
}
func (f *Factory) FromExistingCommsPhone(m *models.CommsPhone) *CommsPhoneTemplate {
o := &CommsPhoneTemplate{f: f, alreadyPersisted: true}
o.E164 = func() string { return m.E164 }
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.DestinationSMSLogs) > 0 {
CommsPhoneMods.AddExistingDestinationSMSLogs(m.R.DestinationSMSLogs...).Apply(ctx, o)
}
if len(m.R.SourceSMSLogs) > 0 {
CommsPhoneMods.AddExistingSourceSMSLogs(m.R.SourceSMSLogs...).Apply(ctx, o)
}
return o
}
func (f *Factory) NewCommsSMSLog(mods ...CommsSMSLogMod) *CommsSMSLogTemplate {
return f.NewCommsSMSLogWithContext(context.Background(), mods...)
}
func (f *Factory) NewCommsSMSLogWithContext(ctx context.Context, mods ...CommsSMSLogMod) *CommsSMSLogTemplate {
o := &CommsSMSLogTemplate{f: f}
if f != nil {
f.baseCommsSMSLogMods.Apply(ctx, o)
}
CommsSMSLogModSlice(mods).Apply(ctx, o)
return o
}
func (f *Factory) FromExistingCommsSMSLog(m *models.CommsSMSLog) *CommsSMSLogTemplate {
o := &CommsSMSLogTemplate{f: f, alreadyPersisted: true}
o.Created = func() time.Time { return m.Created }
o.Destination = func() string { return m.Destination }
o.Source = func() string { return m.Source }
o.Type = func() enums.CommsSmsmessagetype { return m.Type }
ctx := context.Background()
if m.R.DestinationPhone != nil {
CommsSMSLogMods.WithExistingDestinationPhone(m.R.DestinationPhone).Apply(ctx, o)
}
if m.R.SourcePhone != nil {
CommsSMSLogMods.WithExistingSourcePhone(m.R.SourcePhone).Apply(ctx, o)
}
return o
}
func (f *Factory) NewFieldseekerContainerrelate(mods ...FieldseekerContainerrelateMod) *FieldseekerContainerrelateTemplate {
return f.NewFieldseekerContainerrelateWithContext(context.Background(), mods...)
}
@ -2536,6 +2677,7 @@ func (f *Factory) FromExistingPublicreportImage(m *models.PublicreportImage) *Pu
o.ID = func() int32 { return m.ID }
o.ContentType = func() string { return m.ContentType }
o.Created = func() time.Time { return m.Created }
o.Location = func() null.Val[string] { return m.Location }
o.ResolutionX = func() int32 { return m.ResolutionX }
o.ResolutionY = func() int32 { return m.ResolutionY }
o.StorageUUID = func() uuid.UUID { return m.StorageUUID }
@ -3032,6 +3174,38 @@ func (f *Factory) AddBaseArcgisUserPrivilegeMod(mods ...ArcgisUserPrivilegeMod)
f.baseArcgisUserPrivilegeMods = append(f.baseArcgisUserPrivilegeMods, mods...)
}
func (f *Factory) ClearBaseCommsEmailMods() {
f.baseCommsEmailMods = nil
}
func (f *Factory) AddBaseCommsEmailMod(mods ...CommsEmailMod) {
f.baseCommsEmailMods = append(f.baseCommsEmailMods, mods...)
}
func (f *Factory) ClearBaseCommsEmailLogMods() {
f.baseCommsEmailLogMods = nil
}
func (f *Factory) AddBaseCommsEmailLogMod(mods ...CommsEmailLogMod) {
f.baseCommsEmailLogMods = append(f.baseCommsEmailLogMods, mods...)
}
func (f *Factory) ClearBaseCommsPhoneMods() {
f.baseCommsPhoneMods = nil
}
func (f *Factory) AddBaseCommsPhoneMod(mods ...CommsPhoneMod) {
f.baseCommsPhoneMods = append(f.baseCommsPhoneMods, mods...)
}
func (f *Factory) ClearBaseCommsSMSLogMods() {
f.baseCommsSMSLogMods = nil
}
func (f *Factory) AddBaseCommsSMSLogMod(mods ...CommsSMSLogMod) {
f.baseCommsSMSLogMods = append(f.baseCommsSMSLogMods, mods...)
}
func (f *Factory) ClearBaseFieldseekerContainerrelateMods() {
f.baseFieldseekerContainerrelateMods = nil
}

View file

@ -89,6 +89,26 @@ func random_enums_Audiodatatype(f *faker.Faker, limits ...string) enums.Audiodat
return all[f.IntBetween(0, len(all)-1)]
}
func random_enums_CommsEmailmessagetype(f *faker.Faker, limits ...string) enums.CommsEmailmessagetype {
if f == nil {
f = &defaultFaker
}
var e enums.CommsEmailmessagetype
all := e.All()
return all[f.IntBetween(0, len(all)-1)]
}
func random_enums_CommsSmsmessagetype(f *faker.Faker, limits ...string) enums.CommsSmsmessagetype {
if f == nil {
f = &defaultFaker
}
var e enums.CommsSmsmessagetype
all := e.All()
return all[f.IntBetween(0, len(all)-1)]
}
func random_enums_H3aggregationtype(f *faker.Faker, limits ...string) enums.H3aggregationtype {
if f == nil {
f = &defaultFaker

View file

@ -0,0 +1,434 @@
// 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,523 @@
// 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/omit"
"github.com/jaswdr/faker/v2"
"github.com/stephenafamo/bob"
)
type CommsEmailLogMod interface {
Apply(context.Context, *CommsEmailLogTemplate)
}
type CommsEmailLogModFunc func(context.Context, *CommsEmailLogTemplate)
func (f CommsEmailLogModFunc) Apply(ctx context.Context, n *CommsEmailLogTemplate) {
f(ctx, n)
}
type CommsEmailLogModSlice []CommsEmailLogMod
func (mods CommsEmailLogModSlice) Apply(ctx context.Context, n *CommsEmailLogTemplate) {
for _, f := range mods {
f.Apply(ctx, n)
}
}
// 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.CommsEmailmessagetype
r commsEmailLogR
f *Factory
alreadyPersisted bool
}
type commsEmailLogR struct {
DestinationEmail *commsEmailLogRDestinationEmailR
SourcePhone *commsEmailLogRSourcePhoneR
}
type commsEmailLogRDestinationEmailR struct {
o *CommsEmailTemplate
}
type commsEmailLogRSourcePhoneR struct {
o *CommsPhoneTemplate
}
// Apply mods to the CommsEmailLogTemplate
func (o *CommsEmailLogTemplate) Apply(ctx context.Context, mods ...CommsEmailLogMod) {
for _, mod := range mods {
mod.Apply(ctx, o)
}
}
// 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()
rel.R.DestinationEmailLogs = append(rel.R.DestinationEmailLogs, o)
o.Destination = rel.Address // h2
o.R.DestinationEmail = 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
}
}
// BuildSetter returns an *models.CommsEmailLogSetter
// this does nothing with the relationship templates
func (o CommsEmailLogTemplate) BuildSetter() *models.CommsEmailLogSetter {
m := &models.CommsEmailLogSetter{}
if o.Created != nil {
val := o.Created()
m.Created = omit.From(val)
}
if o.Destination != nil {
val := o.Destination()
m.Destination = omit.From(val)
}
if o.Source != nil {
val := o.Source()
m.Source = omit.From(val)
}
if o.Type != nil {
val := o.Type()
m.Type = omit.From(val)
}
return m
}
// BuildManySetter returns an []*models.CommsEmailLogSetter
// this does nothing with the relationship templates
func (o CommsEmailLogTemplate) BuildManySetter(number int) []*models.CommsEmailLogSetter {
m := make([]*models.CommsEmailLogSetter, number)
for i := range m {
m[i] = o.BuildSetter()
}
return m
}
// Build returns an *models.CommsEmailLog
// Related objects are also created and placed in the .R field
// NOTE: Objects are not inserted into the database. Use CommsEmailLogTemplate.Create
func (o CommsEmailLogTemplate) Build() *models.CommsEmailLog {
m := &models.CommsEmailLog{}
if o.Created != nil {
m.Created = o.Created()
}
if o.Destination != nil {
m.Destination = o.Destination()
}
if o.Source != nil {
m.Source = o.Source()
}
if o.Type != nil {
m.Type = o.Type()
}
o.setModelRels(m)
return m
}
// BuildMany returns an models.CommsEmailLogSlice
// Related objects are also created and placed in the .R field
// NOTE: Objects are not inserted into the database. Use CommsEmailLogTemplate.CreateMany
func (o CommsEmailLogTemplate) BuildMany(number int) models.CommsEmailLogSlice {
m := make(models.CommsEmailLogSlice, number)
for i := range m {
m[i] = o.Build()
}
return m
}
func ensureCreatableCommsEmailLog(m *models.CommsEmailLogSetter) {
if !(m.Created.IsValue()) {
val := random_time_Time(nil)
m.Created = omit.From(val)
}
if !(m.Destination.IsValue()) {
val := random_string(nil)
m.Destination = omit.From(val)
}
if !(m.Source.IsValue()) {
val := random_string(nil)
m.Source = omit.From(val)
}
if !(m.Type.IsValue()) {
val := random_enums_CommsEmailmessagetype(nil)
m.Type = omit.From(val)
}
}
// insertOptRels creates and inserts any optional the relationships on *models.CommsEmailLog
// according to the relationships in the template.
// any required relationship should have already exist on the model
func (o *CommsEmailLogTemplate) insertOptRels(ctx context.Context, exec bob.Executor, m *models.CommsEmailLog) error {
var err error
return err
}
// Create builds a commsEmailLog and inserts it into the database
// Relations objects are also inserted and placed in the .R field
func (o *CommsEmailLogTemplate) Create(ctx context.Context, exec bob.Executor) (*models.CommsEmailLog, error) {
var err error
opt := o.BuildSetter()
ensureCreatableCommsEmailLog(opt)
if o.r.DestinationEmail == nil {
CommsEmailLogMods.WithNewDestinationEmail().Apply(ctx, o)
}
var rel0 *models.CommsEmail
if o.r.DestinationEmail.o.alreadyPersisted {
rel0 = o.r.DestinationEmail.o.Build()
} else {
rel0, err = o.r.DestinationEmail.o.Create(ctx, exec)
if err != nil {
return nil, err
}
}
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
if err := o.insertOptRels(ctx, exec, m); err != nil {
return nil, err
}
return m, err
}
// MustCreate builds a commsEmailLog and inserts it into the database
// Relations objects are also inserted and placed in the .R field
// panics if an error occurs
func (o *CommsEmailLogTemplate) MustCreate(ctx context.Context, exec bob.Executor) *models.CommsEmailLog {
m, err := o.Create(ctx, exec)
if err != nil {
panic(err)
}
return m
}
// CreateOrFail builds a commsEmailLog 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 *CommsEmailLogTemplate) CreateOrFail(ctx context.Context, tb testing.TB, exec bob.Executor) *models.CommsEmailLog {
tb.Helper()
m, err := o.Create(ctx, exec)
if err != nil {
tb.Fatal(err)
return nil
}
return m
}
// CreateMany builds multiple commsEmailLogs and inserts them into the database
// Relations objects are also inserted and placed in the .R field
func (o CommsEmailLogTemplate) CreateMany(ctx context.Context, exec bob.Executor, number int) (models.CommsEmailLogSlice, error) {
var err error
m := make(models.CommsEmailLogSlice, number)
for i := range m {
m[i], err = o.Create(ctx, exec)
if err != nil {
return nil, err
}
}
return m, nil
}
// MustCreateMany builds multiple commsEmailLogs and inserts them into the database
// Relations objects are also inserted and placed in the .R field
// panics if an error occurs
func (o CommsEmailLogTemplate) MustCreateMany(ctx context.Context, exec bob.Executor, number int) models.CommsEmailLogSlice {
m, err := o.CreateMany(ctx, exec, number)
if err != nil {
panic(err)
}
return m
}
// CreateManyOrFail builds multiple commsEmailLogs 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 CommsEmailLogTemplate) CreateManyOrFail(ctx context.Context, tb testing.TB, exec bob.Executor, number int) models.CommsEmailLogSlice {
tb.Helper()
m, err := o.CreateMany(ctx, exec, number)
if err != nil {
tb.Fatal(err)
return nil
}
return m
}
// CommsEmailLog has methods that act as mods for the CommsEmailLogTemplate
var CommsEmailLogMods commsEmailLogMods
type commsEmailLogMods struct{}
func (m commsEmailLogMods) RandomizeAllColumns(f *faker.Faker) CommsEmailLogMod {
return CommsEmailLogModSlice{
CommsEmailLogMods.RandomCreated(f),
CommsEmailLogMods.RandomDestination(f),
CommsEmailLogMods.RandomSource(f),
CommsEmailLogMods.RandomType(f),
}
}
// Set the model columns to this value
func (m commsEmailLogMods) Created(val time.Time) CommsEmailLogMod {
return CommsEmailLogModFunc(func(_ context.Context, o *CommsEmailLogTemplate) {
o.Created = func() time.Time { return val }
})
}
// Set the Column from the function
func (m commsEmailLogMods) CreatedFunc(f func() time.Time) CommsEmailLogMod {
return CommsEmailLogModFunc(func(_ context.Context, o *CommsEmailLogTemplate) {
o.Created = f
})
}
// Clear any values for the column
func (m commsEmailLogMods) UnsetCreated() CommsEmailLogMod {
return CommsEmailLogModFunc(func(_ context.Context, o *CommsEmailLogTemplate) {
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 commsEmailLogMods) RandomCreated(f *faker.Faker) CommsEmailLogMod {
return CommsEmailLogModFunc(func(_ context.Context, o *CommsEmailLogTemplate) {
o.Created = func() time.Time {
return random_time_Time(f)
}
})
}
// Set the model columns to this value
func (m commsEmailLogMods) Destination(val string) CommsEmailLogMod {
return CommsEmailLogModFunc(func(_ context.Context, o *CommsEmailLogTemplate) {
o.Destination = func() string { return val }
})
}
// Set the Column from the function
func (m commsEmailLogMods) DestinationFunc(f func() string) CommsEmailLogMod {
return CommsEmailLogModFunc(func(_ context.Context, o *CommsEmailLogTemplate) {
o.Destination = f
})
}
// Clear any values for the column
func (m commsEmailLogMods) UnsetDestination() CommsEmailLogMod {
return CommsEmailLogModFunc(func(_ context.Context, o *CommsEmailLogTemplate) {
o.Destination = nil
})
}
// Generates a random value for the column using the given faker
// if faker is nil, a default faker is used
func (m commsEmailLogMods) RandomDestination(f *faker.Faker) CommsEmailLogMod {
return CommsEmailLogModFunc(func(_ context.Context, o *CommsEmailLogTemplate) {
o.Destination = func() string {
return random_string(f)
}
})
}
// Set the model columns to this value
func (m commsEmailLogMods) Source(val string) CommsEmailLogMod {
return CommsEmailLogModFunc(func(_ context.Context, o *CommsEmailLogTemplate) {
o.Source = func() string { return val }
})
}
// Set the Column from the function
func (m commsEmailLogMods) SourceFunc(f func() string) CommsEmailLogMod {
return CommsEmailLogModFunc(func(_ context.Context, o *CommsEmailLogTemplate) {
o.Source = f
})
}
// Clear any values for the column
func (m commsEmailLogMods) UnsetSource() CommsEmailLogMod {
return CommsEmailLogModFunc(func(_ context.Context, o *CommsEmailLogTemplate) {
o.Source = nil
})
}
// Generates a random value for the column using the given faker
// if faker is nil, a default faker is used
func (m commsEmailLogMods) RandomSource(f *faker.Faker) CommsEmailLogMod {
return CommsEmailLogModFunc(func(_ context.Context, o *CommsEmailLogTemplate) {
o.Source = func() string {
return random_string(f)
}
})
}
// Set the model columns to this value
func (m commsEmailLogMods) Type(val enums.CommsEmailmessagetype) CommsEmailLogMod {
return CommsEmailLogModFunc(func(_ context.Context, o *CommsEmailLogTemplate) {
o.Type = func() enums.CommsEmailmessagetype { return val }
})
}
// Set the Column from the function
func (m commsEmailLogMods) TypeFunc(f func() enums.CommsEmailmessagetype) CommsEmailLogMod {
return CommsEmailLogModFunc(func(_ context.Context, o *CommsEmailLogTemplate) {
o.Type = f
})
}
// Clear any values for the column
func (m commsEmailLogMods) UnsetType() CommsEmailLogMod {
return CommsEmailLogModFunc(func(_ context.Context, o *CommsEmailLogTemplate) {
o.Type = nil
})
}
// Generates a random value for the column using the given faker
// if faker is nil, a default faker is used
func (m commsEmailLogMods) RandomType(f *faker.Faker) CommsEmailLogMod {
return CommsEmailLogModFunc(func(_ context.Context, o *CommsEmailLogTemplate) {
o.Type = func() enums.CommsEmailmessagetype {
return random_enums_CommsEmailmessagetype(f)
}
})
}
func (m commsEmailLogMods) WithParentsCascading() CommsEmailLogMod {
return CommsEmailLogModFunc(func(ctx context.Context, o *CommsEmailLogTemplate) {
if isDone, _ := commsEmailLogWithParentsCascadingCtx.Value(ctx); isDone {
return
}
ctx = commsEmailLogWithParentsCascadingCtx.WithValue(ctx, true)
{
related := o.f.NewCommsEmailWithContext(ctx, CommsEmailMods.WithParentsCascading())
m.WithDestinationEmail(related).Apply(ctx, o)
}
{
related := o.f.NewCommsPhoneWithContext(ctx, CommsPhoneMods.WithParentsCascading())
m.WithSourcePhone(related).Apply(ctx, o)
}
})
}
func (m commsEmailLogMods) WithDestinationEmail(rel *CommsEmailTemplate) CommsEmailLogMod {
return CommsEmailLogModFunc(func(ctx context.Context, o *CommsEmailLogTemplate) {
o.r.DestinationEmail = &commsEmailLogRDestinationEmailR{
o: rel,
}
})
}
func (m commsEmailLogMods) WithNewDestinationEmail(mods ...CommsEmailMod) CommsEmailLogMod {
return CommsEmailLogModFunc(func(ctx context.Context, o *CommsEmailLogTemplate) {
related := o.f.NewCommsEmailWithContext(ctx, mods...)
m.WithDestinationEmail(related).Apply(ctx, o)
})
}
func (m commsEmailLogMods) WithExistingDestinationEmail(em *models.CommsEmail) CommsEmailLogMod {
return CommsEmailLogModFunc(func(ctx context.Context, o *CommsEmailLogTemplate) {
o.r.DestinationEmail = &commsEmailLogRDestinationEmailR{
o: o.f.FromExistingCommsEmail(em),
}
})
}
func (m commsEmailLogMods) WithoutDestinationEmail() CommsEmailLogMod {
return CommsEmailLogModFunc(func(ctx context.Context, o *CommsEmailLogTemplate) {
o.r.DestinationEmail = nil
})
}
func (m commsEmailLogMods) WithSourcePhone(rel *CommsPhoneTemplate) CommsEmailLogMod {
return CommsEmailLogModFunc(func(ctx context.Context, o *CommsEmailLogTemplate) {
o.r.SourcePhone = &commsEmailLogRSourcePhoneR{
o: rel,
}
})
}
func (m commsEmailLogMods) WithNewSourcePhone(mods ...CommsPhoneMod) CommsEmailLogMod {
return CommsEmailLogModFunc(func(ctx context.Context, o *CommsEmailLogTemplate) {
related := o.f.NewCommsPhoneWithContext(ctx, mods...)
m.WithSourcePhone(related).Apply(ctx, o)
})
}
func (m commsEmailLogMods) WithExistingSourcePhone(em *models.CommsPhone) CommsEmailLogMod {
return CommsEmailLogModFunc(func(ctx context.Context, o *CommsEmailLogTemplate) {
o.r.SourcePhone = &commsEmailLogRSourcePhoneR{
o: o.f.FromExistingCommsPhone(em),
}
})
}
func (m commsEmailLogMods) WithoutSourcePhone() CommsEmailLogMod {
return CommsEmailLogModFunc(func(ctx context.Context, o *CommsEmailLogTemplate) {
o.r.SourcePhone = nil
})
}

View file

@ -0,0 +1,562 @@
// 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 CommsPhoneMod interface {
Apply(context.Context, *CommsPhoneTemplate)
}
type CommsPhoneModFunc func(context.Context, *CommsPhoneTemplate)
func (f CommsPhoneModFunc) Apply(ctx context.Context, n *CommsPhoneTemplate) {
f(ctx, n)
}
type CommsPhoneModSlice []CommsPhoneMod
func (mods CommsPhoneModSlice) Apply(ctx context.Context, n *CommsPhoneTemplate) {
for _, f := range mods {
f.Apply(ctx, n)
}
}
// CommsPhoneTemplate is an object representing the database table.
// all columns are optional and should be set by mods
type CommsPhoneTemplate struct {
E164 func() string
IsSubscribed func() bool
r commsPhoneR
f *Factory
alreadyPersisted bool
}
type commsPhoneR struct {
SourceEmailLogs []*commsPhoneRSourceEmailLogsR
DestinationSMSLogs []*commsPhoneRDestinationSMSLogsR
SourceSMSLogs []*commsPhoneRSourceSMSLogsR
}
type commsPhoneRSourceEmailLogsR struct {
number int
o *CommsEmailLogTemplate
}
type commsPhoneRDestinationSMSLogsR struct {
number int
o *CommsSMSLogTemplate
}
type commsPhoneRSourceSMSLogsR struct {
number int
o *CommsSMSLogTemplate
}
// Apply mods to the CommsPhoneTemplate
func (o *CommsPhoneTemplate) Apply(ctx context.Context, mods ...CommsPhoneMod) {
for _, mod := range mods {
mod.Apply(ctx, o)
}
}
// 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.DestinationSMSLogs != nil {
rel := models.CommsSMSLogSlice{}
for _, r := range t.r.DestinationSMSLogs {
related := r.o.BuildMany(r.number)
for _, rel := range related {
rel.Destination = o.E164 // h2
rel.R.DestinationPhone = o
}
rel = append(rel, related...)
}
o.R.DestinationSMSLogs = rel
}
if t.r.SourceSMSLogs != nil {
rel := models.CommsSMSLogSlice{}
for _, r := range t.r.SourceSMSLogs {
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.SourceSMSLogs = rel
}
}
// BuildSetter returns an *models.CommsPhoneSetter
// this does nothing with the relationship templates
func (o CommsPhoneTemplate) BuildSetter() *models.CommsPhoneSetter {
m := &models.CommsPhoneSetter{}
if o.E164 != nil {
val := o.E164()
m.E164 = omit.From(val)
}
if o.IsSubscribed != nil {
val := o.IsSubscribed()
m.IsSubscribed = omit.From(val)
}
return m
}
// BuildManySetter returns an []*models.CommsPhoneSetter
// this does nothing with the relationship templates
func (o CommsPhoneTemplate) BuildManySetter(number int) []*models.CommsPhoneSetter {
m := make([]*models.CommsPhoneSetter, number)
for i := range m {
m[i] = o.BuildSetter()
}
return m
}
// Build returns an *models.CommsPhone
// Related objects are also created and placed in the .R field
// NOTE: Objects are not inserted into the database. Use CommsPhoneTemplate.Create
func (o CommsPhoneTemplate) Build() *models.CommsPhone {
m := &models.CommsPhone{}
if o.E164 != nil {
m.E164 = o.E164()
}
if o.IsSubscribed != nil {
m.IsSubscribed = o.IsSubscribed()
}
o.setModelRels(m)
return m
}
// BuildMany returns an models.CommsPhoneSlice
// Related objects are also created and placed in the .R field
// NOTE: Objects are not inserted into the database. Use CommsPhoneTemplate.CreateMany
func (o CommsPhoneTemplate) BuildMany(number int) models.CommsPhoneSlice {
m := make(models.CommsPhoneSlice, number)
for i := range m {
m[i] = o.Build()
}
return m
}
func ensureCreatableCommsPhone(m *models.CommsPhoneSetter) {
if !(m.E164.IsValue()) {
val := random_string(nil)
m.E164 = 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.CommsPhone
// according to the relationships in the template.
// any required relationship should have already exist on the model
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
}
}
}
}
isDestinationSMSLogsDone, _ := commsPhoneRelDestinationSMSLogsCtx.Value(ctx)
if !isDestinationSMSLogsDone && o.r.DestinationSMSLogs != nil {
ctx = commsPhoneRelDestinationSMSLogsCtx.WithValue(ctx, true)
for _, r := range o.r.DestinationSMSLogs {
if r.o.alreadyPersisted {
m.R.DestinationSMSLogs = append(m.R.DestinationSMSLogs, r.o.Build())
} else {
rel1, err := r.o.CreateMany(ctx, exec, r.number)
if err != nil {
return err
}
err = m.AttachDestinationSMSLogs(ctx, exec, rel1...)
if err != nil {
return err
}
}
}
}
isSourceSMSLogsDone, _ := commsPhoneRelSourceSMSLogsCtx.Value(ctx)
if !isSourceSMSLogsDone && o.r.SourceSMSLogs != nil {
ctx = commsPhoneRelSourceSMSLogsCtx.WithValue(ctx, true)
for _, r := range o.r.SourceSMSLogs {
if r.o.alreadyPersisted {
m.R.SourceSMSLogs = append(m.R.SourceSMSLogs, r.o.Build())
} else {
rel2, err := r.o.CreateMany(ctx, exec, r.number)
if err != nil {
return err
}
err = m.AttachSourceSMSLogs(ctx, exec, rel2...)
if err != nil {
return err
}
}
}
}
return err
}
// Create builds a commsPhone and inserts it into the database
// Relations objects are also inserted and placed in the .R field
func (o *CommsPhoneTemplate) Create(ctx context.Context, exec bob.Executor) (*models.CommsPhone, error) {
var err error
opt := o.BuildSetter()
ensureCreatableCommsPhone(opt)
m, err := models.CommsPhones.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 commsPhone and inserts it into the database
// Relations objects are also inserted and placed in the .R field
// panics if an error occurs
func (o *CommsPhoneTemplate) MustCreate(ctx context.Context, exec bob.Executor) *models.CommsPhone {
m, err := o.Create(ctx, exec)
if err != nil {
panic(err)
}
return m
}
// CreateOrFail builds a commsPhone 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 *CommsPhoneTemplate) CreateOrFail(ctx context.Context, tb testing.TB, exec bob.Executor) *models.CommsPhone {
tb.Helper()
m, err := o.Create(ctx, exec)
if err != nil {
tb.Fatal(err)
return nil
}
return m
}
// CreateMany builds multiple commsPhones and inserts them into the database
// Relations objects are also inserted and placed in the .R field
func (o CommsPhoneTemplate) CreateMany(ctx context.Context, exec bob.Executor, number int) (models.CommsPhoneSlice, error) {
var err error
m := make(models.CommsPhoneSlice, number)
for i := range m {
m[i], err = o.Create(ctx, exec)
if err != nil {
return nil, err
}
}
return m, nil
}
// MustCreateMany builds multiple commsPhones and inserts them into the database
// Relations objects are also inserted and placed in the .R field
// panics if an error occurs
func (o CommsPhoneTemplate) MustCreateMany(ctx context.Context, exec bob.Executor, number int) models.CommsPhoneSlice {
m, err := o.CreateMany(ctx, exec, number)
if err != nil {
panic(err)
}
return m
}
// CreateManyOrFail builds multiple commsPhones 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 CommsPhoneTemplate) CreateManyOrFail(ctx context.Context, tb testing.TB, exec bob.Executor, number int) models.CommsPhoneSlice {
tb.Helper()
m, err := o.CreateMany(ctx, exec, number)
if err != nil {
tb.Fatal(err)
return nil
}
return m
}
// CommsPhone has methods that act as mods for the CommsPhoneTemplate
var CommsPhoneMods commsPhoneMods
type commsPhoneMods struct{}
func (m commsPhoneMods) RandomizeAllColumns(f *faker.Faker) CommsPhoneMod {
return CommsPhoneModSlice{
CommsPhoneMods.RandomE164(f),
CommsPhoneMods.RandomIsSubscribed(f),
}
}
// Set the model columns to this value
func (m commsPhoneMods) E164(val string) CommsPhoneMod {
return CommsPhoneModFunc(func(_ context.Context, o *CommsPhoneTemplate) {
o.E164 = func() string { return val }
})
}
// Set the Column from the function
func (m commsPhoneMods) E164Func(f func() string) CommsPhoneMod {
return CommsPhoneModFunc(func(_ context.Context, o *CommsPhoneTemplate) {
o.E164 = f
})
}
// Clear any values for the column
func (m commsPhoneMods) UnsetE164() CommsPhoneMod {
return CommsPhoneModFunc(func(_ context.Context, o *CommsPhoneTemplate) {
o.E164 = nil
})
}
// Generates a random value for the column using the given faker
// if faker is nil, a default faker is used
func (m commsPhoneMods) RandomE164(f *faker.Faker) CommsPhoneMod {
return CommsPhoneModFunc(func(_ context.Context, o *CommsPhoneTemplate) {
o.E164 = func() string {
return random_string(f)
}
})
}
// Set the model columns to this value
func (m commsPhoneMods) IsSubscribed(val bool) CommsPhoneMod {
return CommsPhoneModFunc(func(_ context.Context, o *CommsPhoneTemplate) {
o.IsSubscribed = func() bool { return val }
})
}
// Set the Column from the function
func (m commsPhoneMods) IsSubscribedFunc(f func() bool) CommsPhoneMod {
return CommsPhoneModFunc(func(_ context.Context, o *CommsPhoneTemplate) {
o.IsSubscribed = f
})
}
// Clear any values for the column
func (m commsPhoneMods) UnsetIsSubscribed() CommsPhoneMod {
return CommsPhoneModFunc(func(_ context.Context, o *CommsPhoneTemplate) {
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 commsPhoneMods) RandomIsSubscribed(f *faker.Faker) CommsPhoneMod {
return CommsPhoneModFunc(func(_ context.Context, o *CommsPhoneTemplate) {
o.IsSubscribed = func() bool {
return random_bool(f)
}
})
}
func (m commsPhoneMods) WithParentsCascading() CommsPhoneMod {
return CommsPhoneModFunc(func(ctx context.Context, o *CommsPhoneTemplate) {
if isDone, _ := commsPhoneWithParentsCascadingCtx.Value(ctx); isDone {
return
}
ctx = commsPhoneWithParentsCascadingCtx.WithValue(ctx, true)
})
}
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) WithDestinationSMSLogs(number int, related *CommsSMSLogTemplate) CommsPhoneMod {
return CommsPhoneModFunc(func(ctx context.Context, o *CommsPhoneTemplate) {
o.r.DestinationSMSLogs = []*commsPhoneRDestinationSMSLogsR{{
number: number,
o: related,
}}
})
}
func (m commsPhoneMods) WithNewDestinationSMSLogs(number int, mods ...CommsSMSLogMod) CommsPhoneMod {
return CommsPhoneModFunc(func(ctx context.Context, o *CommsPhoneTemplate) {
related := o.f.NewCommsSMSLogWithContext(ctx, mods...)
m.WithDestinationSMSLogs(number, related).Apply(ctx, o)
})
}
func (m commsPhoneMods) AddDestinationSMSLogs(number int, related *CommsSMSLogTemplate) CommsPhoneMod {
return CommsPhoneModFunc(func(ctx context.Context, o *CommsPhoneTemplate) {
o.r.DestinationSMSLogs = append(o.r.DestinationSMSLogs, &commsPhoneRDestinationSMSLogsR{
number: number,
o: related,
})
})
}
func (m commsPhoneMods) AddNewDestinationSMSLogs(number int, mods ...CommsSMSLogMod) CommsPhoneMod {
return CommsPhoneModFunc(func(ctx context.Context, o *CommsPhoneTemplate) {
related := o.f.NewCommsSMSLogWithContext(ctx, mods...)
m.AddDestinationSMSLogs(number, related).Apply(ctx, o)
})
}
func (m commsPhoneMods) AddExistingDestinationSMSLogs(existingModels ...*models.CommsSMSLog) CommsPhoneMod {
return CommsPhoneModFunc(func(ctx context.Context, o *CommsPhoneTemplate) {
for _, em := range existingModels {
o.r.DestinationSMSLogs = append(o.r.DestinationSMSLogs, &commsPhoneRDestinationSMSLogsR{
o: o.f.FromExistingCommsSMSLog(em),
})
}
})
}
func (m commsPhoneMods) WithoutDestinationSMSLogs() CommsPhoneMod {
return CommsPhoneModFunc(func(ctx context.Context, o *CommsPhoneTemplate) {
o.r.DestinationSMSLogs = nil
})
}
func (m commsPhoneMods) WithSourceSMSLogs(number int, related *CommsSMSLogTemplate) CommsPhoneMod {
return CommsPhoneModFunc(func(ctx context.Context, o *CommsPhoneTemplate) {
o.r.SourceSMSLogs = []*commsPhoneRSourceSMSLogsR{{
number: number,
o: related,
}}
})
}
func (m commsPhoneMods) WithNewSourceSMSLogs(number int, mods ...CommsSMSLogMod) CommsPhoneMod {
return CommsPhoneModFunc(func(ctx context.Context, o *CommsPhoneTemplate) {
related := o.f.NewCommsSMSLogWithContext(ctx, mods...)
m.WithSourceSMSLogs(number, related).Apply(ctx, o)
})
}
func (m commsPhoneMods) AddSourceSMSLogs(number int, related *CommsSMSLogTemplate) CommsPhoneMod {
return CommsPhoneModFunc(func(ctx context.Context, o *CommsPhoneTemplate) {
o.r.SourceSMSLogs = append(o.r.SourceSMSLogs, &commsPhoneRSourceSMSLogsR{
number: number,
o: related,
})
})
}
func (m commsPhoneMods) AddNewSourceSMSLogs(number int, mods ...CommsSMSLogMod) CommsPhoneMod {
return CommsPhoneModFunc(func(ctx context.Context, o *CommsPhoneTemplate) {
related := o.f.NewCommsSMSLogWithContext(ctx, mods...)
m.AddSourceSMSLogs(number, related).Apply(ctx, o)
})
}
func (m commsPhoneMods) AddExistingSourceSMSLogs(existingModels ...*models.CommsSMSLog) CommsPhoneMod {
return CommsPhoneModFunc(func(ctx context.Context, o *CommsPhoneTemplate) {
for _, em := range existingModels {
o.r.SourceSMSLogs = append(o.r.SourceSMSLogs, &commsPhoneRSourceSMSLogsR{
o: o.f.FromExistingCommsSMSLog(em),
})
}
})
}
func (m commsPhoneMods) WithoutSourceSMSLogs() CommsPhoneMod {
return CommsPhoneModFunc(func(ctx context.Context, o *CommsPhoneTemplate) {
o.r.SourceSMSLogs = nil
})
}

View file

@ -0,0 +1,523 @@
// 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/omit"
"github.com/jaswdr/faker/v2"
"github.com/stephenafamo/bob"
)
type CommsSMSLogMod interface {
Apply(context.Context, *CommsSMSLogTemplate)
}
type CommsSMSLogModFunc func(context.Context, *CommsSMSLogTemplate)
func (f CommsSMSLogModFunc) Apply(ctx context.Context, n *CommsSMSLogTemplate) {
f(ctx, n)
}
type CommsSMSLogModSlice []CommsSMSLogMod
func (mods CommsSMSLogModSlice) Apply(ctx context.Context, n *CommsSMSLogTemplate) {
for _, f := range mods {
f.Apply(ctx, n)
}
}
// CommsSMSLogTemplate is an object representing the database table.
// all columns are optional and should be set by mods
type CommsSMSLogTemplate struct {
Created func() time.Time
Destination func() string
Source func() string
Type func() enums.CommsSmsmessagetype
r commsSMSLogR
f *Factory
alreadyPersisted bool
}
type commsSMSLogR struct {
DestinationPhone *commsSMSLogRDestinationPhoneR
SourcePhone *commsSMSLogRSourcePhoneR
}
type commsSMSLogRDestinationPhoneR struct {
o *CommsPhoneTemplate
}
type commsSMSLogRSourcePhoneR struct {
o *CommsPhoneTemplate
}
// Apply mods to the CommsSMSLogTemplate
func (o *CommsSMSLogTemplate) Apply(ctx context.Context, mods ...CommsSMSLogMod) {
for _, mod := range mods {
mod.Apply(ctx, o)
}
}
// setModelRels creates and sets the relationships on *models.CommsSMSLog
// according to the relationships in the template. Nothing is inserted into the db
func (t CommsSMSLogTemplate) setModelRels(o *models.CommsSMSLog) {
if t.r.DestinationPhone != nil {
rel := t.r.DestinationPhone.o.Build()
rel.R.DestinationSMSLogs = append(rel.R.DestinationSMSLogs, o)
o.Destination = rel.E164 // h2
o.R.DestinationPhone = rel
}
if t.r.SourcePhone != nil {
rel := t.r.SourcePhone.o.Build()
rel.R.SourceSMSLogs = append(rel.R.SourceSMSLogs, o)
o.Source = rel.E164 // h2
o.R.SourcePhone = rel
}
}
// BuildSetter returns an *models.CommsSMSLogSetter
// this does nothing with the relationship templates
func (o CommsSMSLogTemplate) BuildSetter() *models.CommsSMSLogSetter {
m := &models.CommsSMSLogSetter{}
if o.Created != nil {
val := o.Created()
m.Created = omit.From(val)
}
if o.Destination != nil {
val := o.Destination()
m.Destination = omit.From(val)
}
if o.Source != nil {
val := o.Source()
m.Source = omit.From(val)
}
if o.Type != nil {
val := o.Type()
m.Type = omit.From(val)
}
return m
}
// BuildManySetter returns an []*models.CommsSMSLogSetter
// this does nothing with the relationship templates
func (o CommsSMSLogTemplate) BuildManySetter(number int) []*models.CommsSMSLogSetter {
m := make([]*models.CommsSMSLogSetter, number)
for i := range m {
m[i] = o.BuildSetter()
}
return m
}
// Build returns an *models.CommsSMSLog
// Related objects are also created and placed in the .R field
// NOTE: Objects are not inserted into the database. Use CommsSMSLogTemplate.Create
func (o CommsSMSLogTemplate) Build() *models.CommsSMSLog {
m := &models.CommsSMSLog{}
if o.Created != nil {
m.Created = o.Created()
}
if o.Destination != nil {
m.Destination = o.Destination()
}
if o.Source != nil {
m.Source = o.Source()
}
if o.Type != nil {
m.Type = o.Type()
}
o.setModelRels(m)
return m
}
// BuildMany returns an models.CommsSMSLogSlice
// Related objects are also created and placed in the .R field
// NOTE: Objects are not inserted into the database. Use CommsSMSLogTemplate.CreateMany
func (o CommsSMSLogTemplate) BuildMany(number int) models.CommsSMSLogSlice {
m := make(models.CommsSMSLogSlice, number)
for i := range m {
m[i] = o.Build()
}
return m
}
func ensureCreatableCommsSMSLog(m *models.CommsSMSLogSetter) {
if !(m.Created.IsValue()) {
val := random_time_Time(nil)
m.Created = omit.From(val)
}
if !(m.Destination.IsValue()) {
val := random_string(nil)
m.Destination = omit.From(val)
}
if !(m.Source.IsValue()) {
val := random_string(nil)
m.Source = omit.From(val)
}
if !(m.Type.IsValue()) {
val := random_enums_CommsSmsmessagetype(nil)
m.Type = omit.From(val)
}
}
// insertOptRels creates and inserts any optional the relationships on *models.CommsSMSLog
// according to the relationships in the template.
// any required relationship should have already exist on the model
func (o *CommsSMSLogTemplate) insertOptRels(ctx context.Context, exec bob.Executor, m *models.CommsSMSLog) error {
var err error
return err
}
// Create builds a commsSMSLog and inserts it into the database
// Relations objects are also inserted and placed in the .R field
func (o *CommsSMSLogTemplate) Create(ctx context.Context, exec bob.Executor) (*models.CommsSMSLog, error) {
var err error
opt := o.BuildSetter()
ensureCreatableCommsSMSLog(opt)
if o.r.DestinationPhone == nil {
CommsSMSLogMods.WithNewDestinationPhone().Apply(ctx, o)
}
var rel0 *models.CommsPhone
if o.r.DestinationPhone.o.alreadyPersisted {
rel0 = o.r.DestinationPhone.o.Build()
} else {
rel0, err = o.r.DestinationPhone.o.Create(ctx, exec)
if err != nil {
return nil, err
}
}
opt.Destination = omit.From(rel0.E164)
if o.r.SourcePhone == nil {
CommsSMSLogMods.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.CommsSMSLogs.Insert(opt).One(ctx, exec)
if err != nil {
return nil, err
}
m.R.DestinationPhone = rel0
m.R.SourcePhone = rel1
if err := o.insertOptRels(ctx, exec, m); err != nil {
return nil, err
}
return m, err
}
// MustCreate builds a commsSMSLog and inserts it into the database
// Relations objects are also inserted and placed in the .R field
// panics if an error occurs
func (o *CommsSMSLogTemplate) MustCreate(ctx context.Context, exec bob.Executor) *models.CommsSMSLog {
m, err := o.Create(ctx, exec)
if err != nil {
panic(err)
}
return m
}
// CreateOrFail builds a commsSMSLog 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 *CommsSMSLogTemplate) CreateOrFail(ctx context.Context, tb testing.TB, exec bob.Executor) *models.CommsSMSLog {
tb.Helper()
m, err := o.Create(ctx, exec)
if err != nil {
tb.Fatal(err)
return nil
}
return m
}
// CreateMany builds multiple commsSMSLogs and inserts them into the database
// Relations objects are also inserted and placed in the .R field
func (o CommsSMSLogTemplate) CreateMany(ctx context.Context, exec bob.Executor, number int) (models.CommsSMSLogSlice, error) {
var err error
m := make(models.CommsSMSLogSlice, number)
for i := range m {
m[i], err = o.Create(ctx, exec)
if err != nil {
return nil, err
}
}
return m, nil
}
// MustCreateMany builds multiple commsSMSLogs and inserts them into the database
// Relations objects are also inserted and placed in the .R field
// panics if an error occurs
func (o CommsSMSLogTemplate) MustCreateMany(ctx context.Context, exec bob.Executor, number int) models.CommsSMSLogSlice {
m, err := o.CreateMany(ctx, exec, number)
if err != nil {
panic(err)
}
return m
}
// CreateManyOrFail builds multiple commsSMSLogs 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 CommsSMSLogTemplate) CreateManyOrFail(ctx context.Context, tb testing.TB, exec bob.Executor, number int) models.CommsSMSLogSlice {
tb.Helper()
m, err := o.CreateMany(ctx, exec, number)
if err != nil {
tb.Fatal(err)
return nil
}
return m
}
// CommsSMSLog has methods that act as mods for the CommsSMSLogTemplate
var CommsSMSLogMods commsSMSLogMods
type commsSMSLogMods struct{}
func (m commsSMSLogMods) RandomizeAllColumns(f *faker.Faker) CommsSMSLogMod {
return CommsSMSLogModSlice{
CommsSMSLogMods.RandomCreated(f),
CommsSMSLogMods.RandomDestination(f),
CommsSMSLogMods.RandomSource(f),
CommsSMSLogMods.RandomType(f),
}
}
// Set the model columns to this value
func (m commsSMSLogMods) Created(val time.Time) CommsSMSLogMod {
return CommsSMSLogModFunc(func(_ context.Context, o *CommsSMSLogTemplate) {
o.Created = func() time.Time { return val }
})
}
// Set the Column from the function
func (m commsSMSLogMods) CreatedFunc(f func() time.Time) CommsSMSLogMod {
return CommsSMSLogModFunc(func(_ context.Context, o *CommsSMSLogTemplate) {
o.Created = f
})
}
// Clear any values for the column
func (m commsSMSLogMods) UnsetCreated() CommsSMSLogMod {
return CommsSMSLogModFunc(func(_ context.Context, o *CommsSMSLogTemplate) {
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 commsSMSLogMods) RandomCreated(f *faker.Faker) CommsSMSLogMod {
return CommsSMSLogModFunc(func(_ context.Context, o *CommsSMSLogTemplate) {
o.Created = func() time.Time {
return random_time_Time(f)
}
})
}
// Set the model columns to this value
func (m commsSMSLogMods) Destination(val string) CommsSMSLogMod {
return CommsSMSLogModFunc(func(_ context.Context, o *CommsSMSLogTemplate) {
o.Destination = func() string { return val }
})
}
// Set the Column from the function
func (m commsSMSLogMods) DestinationFunc(f func() string) CommsSMSLogMod {
return CommsSMSLogModFunc(func(_ context.Context, o *CommsSMSLogTemplate) {
o.Destination = f
})
}
// Clear any values for the column
func (m commsSMSLogMods) UnsetDestination() CommsSMSLogMod {
return CommsSMSLogModFunc(func(_ context.Context, o *CommsSMSLogTemplate) {
o.Destination = nil
})
}
// Generates a random value for the column using the given faker
// if faker is nil, a default faker is used
func (m commsSMSLogMods) RandomDestination(f *faker.Faker) CommsSMSLogMod {
return CommsSMSLogModFunc(func(_ context.Context, o *CommsSMSLogTemplate) {
o.Destination = func() string {
return random_string(f)
}
})
}
// Set the model columns to this value
func (m commsSMSLogMods) Source(val string) CommsSMSLogMod {
return CommsSMSLogModFunc(func(_ context.Context, o *CommsSMSLogTemplate) {
o.Source = func() string { return val }
})
}
// Set the Column from the function
func (m commsSMSLogMods) SourceFunc(f func() string) CommsSMSLogMod {
return CommsSMSLogModFunc(func(_ context.Context, o *CommsSMSLogTemplate) {
o.Source = f
})
}
// Clear any values for the column
func (m commsSMSLogMods) UnsetSource() CommsSMSLogMod {
return CommsSMSLogModFunc(func(_ context.Context, o *CommsSMSLogTemplate) {
o.Source = nil
})
}
// Generates a random value for the column using the given faker
// if faker is nil, a default faker is used
func (m commsSMSLogMods) RandomSource(f *faker.Faker) CommsSMSLogMod {
return CommsSMSLogModFunc(func(_ context.Context, o *CommsSMSLogTemplate) {
o.Source = func() string {
return random_string(f)
}
})
}
// Set the model columns to this value
func (m commsSMSLogMods) Type(val enums.CommsSmsmessagetype) CommsSMSLogMod {
return CommsSMSLogModFunc(func(_ context.Context, o *CommsSMSLogTemplate) {
o.Type = func() enums.CommsSmsmessagetype { return val }
})
}
// Set the Column from the function
func (m commsSMSLogMods) TypeFunc(f func() enums.CommsSmsmessagetype) CommsSMSLogMod {
return CommsSMSLogModFunc(func(_ context.Context, o *CommsSMSLogTemplate) {
o.Type = f
})
}
// Clear any values for the column
func (m commsSMSLogMods) UnsetType() CommsSMSLogMod {
return CommsSMSLogModFunc(func(_ context.Context, o *CommsSMSLogTemplate) {
o.Type = nil
})
}
// Generates a random value for the column using the given faker
// if faker is nil, a default faker is used
func (m commsSMSLogMods) RandomType(f *faker.Faker) CommsSMSLogMod {
return CommsSMSLogModFunc(func(_ context.Context, o *CommsSMSLogTemplate) {
o.Type = func() enums.CommsSmsmessagetype {
return random_enums_CommsSmsmessagetype(f)
}
})
}
func (m commsSMSLogMods) WithParentsCascading() CommsSMSLogMod {
return CommsSMSLogModFunc(func(ctx context.Context, o *CommsSMSLogTemplate) {
if isDone, _ := commsSMSLogWithParentsCascadingCtx.Value(ctx); isDone {
return
}
ctx = commsSMSLogWithParentsCascadingCtx.WithValue(ctx, true)
{
related := o.f.NewCommsPhoneWithContext(ctx, CommsPhoneMods.WithParentsCascading())
m.WithDestinationPhone(related).Apply(ctx, o)
}
{
related := o.f.NewCommsPhoneWithContext(ctx, CommsPhoneMods.WithParentsCascading())
m.WithSourcePhone(related).Apply(ctx, o)
}
})
}
func (m commsSMSLogMods) WithDestinationPhone(rel *CommsPhoneTemplate) CommsSMSLogMod {
return CommsSMSLogModFunc(func(ctx context.Context, o *CommsSMSLogTemplate) {
o.r.DestinationPhone = &commsSMSLogRDestinationPhoneR{
o: rel,
}
})
}
func (m commsSMSLogMods) WithNewDestinationPhone(mods ...CommsPhoneMod) CommsSMSLogMod {
return CommsSMSLogModFunc(func(ctx context.Context, o *CommsSMSLogTemplate) {
related := o.f.NewCommsPhoneWithContext(ctx, mods...)
m.WithDestinationPhone(related).Apply(ctx, o)
})
}
func (m commsSMSLogMods) WithExistingDestinationPhone(em *models.CommsPhone) CommsSMSLogMod {
return CommsSMSLogModFunc(func(ctx context.Context, o *CommsSMSLogTemplate) {
o.r.DestinationPhone = &commsSMSLogRDestinationPhoneR{
o: o.f.FromExistingCommsPhone(em),
}
})
}
func (m commsSMSLogMods) WithoutDestinationPhone() CommsSMSLogMod {
return CommsSMSLogModFunc(func(ctx context.Context, o *CommsSMSLogTemplate) {
o.r.DestinationPhone = nil
})
}
func (m commsSMSLogMods) WithSourcePhone(rel *CommsPhoneTemplate) CommsSMSLogMod {
return CommsSMSLogModFunc(func(ctx context.Context, o *CommsSMSLogTemplate) {
o.r.SourcePhone = &commsSMSLogRSourcePhoneR{
o: rel,
}
})
}
func (m commsSMSLogMods) WithNewSourcePhone(mods ...CommsPhoneMod) CommsSMSLogMod {
return CommsSMSLogModFunc(func(ctx context.Context, o *CommsSMSLogTemplate) {
related := o.f.NewCommsPhoneWithContext(ctx, mods...)
m.WithSourcePhone(related).Apply(ctx, o)
})
}
func (m commsSMSLogMods) WithExistingSourcePhone(em *models.CommsPhone) CommsSMSLogMod {
return CommsSMSLogModFunc(func(ctx context.Context, o *CommsSMSLogTemplate) {
o.r.SourcePhone = &commsSMSLogRSourcePhoneR{
o: o.f.FromExistingCommsPhone(em),
}
})
}
func (m commsSMSLogMods) WithoutSourcePhone() CommsSMSLogMod {
return CommsSMSLogModFunc(func(ctx context.Context, o *CommsSMSLogTemplate) {
o.r.SourcePhone = nil
})
}

View file

@ -9,7 +9,9 @@ import (
"time"
models "github.com/Gleipnir-Technology/nidus-sync/db/models"
"github.com/aarondl/opt/null"
"github.com/aarondl/opt/omit"
"github.com/aarondl/opt/omitnull"
"github.com/google/uuid"
"github.com/jaswdr/faker/v2"
"github.com/stephenafamo/bob"
@ -39,6 +41,7 @@ type PublicreportImageTemplate struct {
ID func() int32
ContentType func() string
Created func() time.Time
Location func() null.Val[string]
ResolutionX func() int32
ResolutionY func() int32
StorageUUID func() uuid.UUID
@ -135,6 +138,10 @@ func (o PublicreportImageTemplate) BuildSetter() *models.PublicreportImageSetter
val := o.Created()
m.Created = omit.From(val)
}
if o.Location != nil {
val := o.Location()
m.Location = omitnull.FromNull(val)
}
if o.ResolutionX != nil {
val := o.ResolutionX()
m.ResolutionX = omit.From(val)
@ -186,6 +193,9 @@ func (o PublicreportImageTemplate) Build() *models.PublicreportImage {
if o.Created != nil {
m.Created = o.Created()
}
if o.Location != nil {
m.Location = o.Location()
}
if o.ResolutionX != nil {
m.ResolutionX = o.ResolutionX()
}
@ -412,6 +422,7 @@ func (m publicreportImageMods) RandomizeAllColumns(f *faker.Faker) PublicreportI
PublicreportImageMods.RandomID(f),
PublicreportImageMods.RandomContentType(f),
PublicreportImageMods.RandomCreated(f),
PublicreportImageMods.RandomLocation(f),
PublicreportImageMods.RandomResolutionX(f),
PublicreportImageMods.RandomResolutionY(f),
PublicreportImageMods.RandomStorageUUID(f),
@ -513,6 +524,59 @@ func (m publicreportImageMods) RandomCreated(f *faker.Faker) PublicreportImageMo
})
}
// Set the model columns to this value
func (m publicreportImageMods) Location(val null.Val[string]) PublicreportImageMod {
return PublicreportImageModFunc(func(_ context.Context, o *PublicreportImageTemplate) {
o.Location = func() null.Val[string] { return val }
})
}
// Set the Column from the function
func (m publicreportImageMods) LocationFunc(f func() null.Val[string]) PublicreportImageMod {
return PublicreportImageModFunc(func(_ context.Context, o *PublicreportImageTemplate) {
o.Location = f
})
}
// Clear any values for the column
func (m publicreportImageMods) UnsetLocation() PublicreportImageMod {
return PublicreportImageModFunc(func(_ context.Context, o *PublicreportImageTemplate) {
o.Location = nil
})
}
// Generates a random value for the column using the given faker
// if faker is nil, a default faker is used
// The generated value is sometimes null
func (m publicreportImageMods) RandomLocation(f *faker.Faker) PublicreportImageMod {
return PublicreportImageModFunc(func(_ context.Context, o *PublicreportImageTemplate) {
o.Location = func() null.Val[string] {
if f == nil {
f = &defaultFaker
}
val := random_string(f)
return null.From(val)
}
})
}
// Generates a random value for the column using the given faker
// if faker is nil, a default faker is used
// The generated value is never null
func (m publicreportImageMods) RandomLocationNotNull(f *faker.Faker) PublicreportImageMod {
return PublicreportImageModFunc(func(_ context.Context, o *PublicreportImageTemplate) {
o.Location = func() null.Val[string] {
if f == nil {
f = &defaultFaker
}
val := random_string(f)
return null.From(val)
}
})
}
// Set the model columns to this value
func (m publicreportImageMods) ResolutionX(val int32) PublicreportImageMod {
return PublicreportImageModFunc(func(_ context.Context, o *PublicreportImageTemplate) {

View file

@ -0,0 +1,37 @@
-- +goose Up
CREATE SCHEMA comms;
CREATE TYPE comms.SMSMessageType AS ENUM (
'report-subscription-confirmation',
'report-status-scheduled',
'report-status-complete'
);
CREATE TYPE comms.EmailMessageType AS ENUM (
'report-subscription-confirmation',
'report-status-scheduled',
'report-status-complete'
);
CREATE TABLE comms.phone (
e164 TEXT NOT NULL,
is_subscribed BOOLEAN NOT NULL,
PRIMARY KEY (e164)
);
CREATE TABLE comms.sms_log (
created TIMESTAMP WITHOUT TIME ZONE NOT NULL,
destination TEXT NOT NULL REFERENCES comms.phone(e164),
source TEXT NOT NULL REFERENCES comms.phone(e164),
type comms.SMSMessageType NOT NULL,
PRIMARY KEY (destination, source, type)
);
CREATE TABLE comms.email (
address TEXT NOT NULL,
confirmed BOOLEAN NOT NULL,
is_subscribed BOOLEAN NOT NULL,
PRIMARY KEY(address)
);
CREATE TABLE comms.email_log (
created TIMESTAMP WITHOUT TIME ZONE NOT NULL,
destination TEXT NOT NULL REFERENCES comms.email(address),
source TEXT NOT NULL REFERENCES comms.phone(e164),
type comms.EmailMessageType NOT NULL,
PRIMARY KEY(destination, source, type)
);

View file

@ -22,6 +22,8 @@ var (
type preloadCounts struct {
ArcgisUser arcgisuserCountPreloader
CommsEmail commsEmailCountPreloader
CommsPhone commsPhoneCountPreloader
NoteAudio noteAudioCountPreloader
NoteImage noteImageCountPreloader
Organization organizationCountPreloader
@ -34,6 +36,8 @@ type preloadCounts struct {
func getPreloadCount() preloadCounts {
return preloadCounts{
ArcgisUser: buildArcgisUserCountPreloader(),
CommsEmail: buildCommsEmailCountPreloader(),
CommsPhone: buildCommsPhoneCountPreloader(),
NoteAudio: buildNoteAudioCountPreloader(),
NoteImage: buildNoteImageCountPreloader(),
Organization: buildOrganizationCountPreloader(),
@ -46,6 +50,8 @@ func getPreloadCount() preloadCounts {
type thenLoadCounts[Q orm.Loadable] struct {
ArcgisUser arcgisuserCountThenLoader[Q]
CommsEmail commsEmailCountThenLoader[Q]
CommsPhone commsPhoneCountThenLoader[Q]
NoteAudio noteAudioCountThenLoader[Q]
NoteImage noteImageCountThenLoader[Q]
Organization organizationCountThenLoader[Q]
@ -58,6 +64,8 @@ type thenLoadCounts[Q orm.Loadable] struct {
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](),

View file

@ -34,6 +34,10 @@ 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]]
CommsEmailLogs joinSet[commsEmailLogJoins[Q]]
CommsPhones joinSet[commsPhoneJoins[Q]]
CommsSMSLogs joinSet[commsSMSLogJoins[Q]]
FieldseekerContainerrelates joinSet[fieldseekerContainerrelateJoins[Q]]
FieldseekerFieldscoutinglogs joinSet[fieldseekerFieldscoutinglogJoins[Q]]
FieldseekerHabitatrelates joinSet[fieldseekerHabitatrelateJoins[Q]]
@ -94,6 +98,10 @@ 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),
CommsEmailLogs: buildJoinSet[commsEmailLogJoins[Q]](CommsEmailLogs.Columns, buildCommsEmailLogJoins),
CommsPhones: buildJoinSet[commsPhoneJoins[Q]](CommsPhones.Columns, buildCommsPhoneJoins),
CommsSMSLogs: buildJoinSet[commsSMSLogJoins[Q]](CommsSMSLogs.Columns, buildCommsSMSLogJoins),
FieldseekerContainerrelates: buildJoinSet[fieldseekerContainerrelateJoins[Q]](FieldseekerContainerrelates.Columns, buildFieldseekerContainerrelateJoins),
FieldseekerFieldscoutinglogs: buildJoinSet[fieldseekerFieldscoutinglogJoins[Q]](FieldseekerFieldscoutinglogs.Columns, buildFieldseekerFieldscoutinglogJoins),
FieldseekerHabitatrelates: buildJoinSet[fieldseekerHabitatrelateJoins[Q]](FieldseekerHabitatrelates.Columns, buildFieldseekerHabitatrelateJoins),

View file

@ -19,6 +19,10 @@ var Preload = getPreloaders()
type preloaders struct {
ArcgisUser arcgisuserPreloader
ArcgisUserPrivilege arcgisUserPrivilegePreloader
CommsEmail commsEmailPreloader
CommsEmailLog commsEmailLogPreloader
CommsPhone commsPhonePreloader
CommsSMSLog commsSMSLogPreloader
FieldseekerContainerrelate fieldseekerContainerrelatePreloader
FieldseekerFieldscoutinglog fieldseekerFieldscoutinglogPreloader
FieldseekerHabitatrelate fieldseekerHabitatrelatePreloader
@ -71,6 +75,10 @@ func getPreloaders() preloaders {
return preloaders{
ArcgisUser: buildArcgisUserPreloader(),
ArcgisUserPrivilege: buildArcgisUserPrivilegePreloader(),
CommsEmail: buildCommsEmailPreloader(),
CommsEmailLog: buildCommsEmailLogPreloader(),
CommsPhone: buildCommsPhonePreloader(),
CommsSMSLog: buildCommsSMSLogPreloader(),
FieldseekerContainerrelate: buildFieldseekerContainerrelatePreloader(),
FieldseekerFieldscoutinglog: buildFieldseekerFieldscoutinglogPreloader(),
FieldseekerHabitatrelate: buildFieldseekerHabitatrelatePreloader(),
@ -129,6 +137,10 @@ var (
type thenLoaders[Q orm.Loadable] struct {
ArcgisUser arcgisuserThenLoader[Q]
ArcgisUserPrivilege arcgisUserPrivilegeThenLoader[Q]
CommsEmail commsEmailThenLoader[Q]
CommsEmailLog commsEmailLogThenLoader[Q]
CommsPhone commsPhoneThenLoader[Q]
CommsSMSLog commsSMSLogThenLoader[Q]
FieldseekerContainerrelate fieldseekerContainerrelateThenLoader[Q]
FieldseekerFieldscoutinglog fieldseekerFieldscoutinglogThenLoader[Q]
FieldseekerHabitatrelate fieldseekerHabitatrelateThenLoader[Q]
@ -181,6 +193,10 @@ func getThenLoaders[Q orm.Loadable]() thenLoaders[Q] {
return thenLoaders[Q]{
ArcgisUser: buildArcgisUserThenLoader[Q](),
ArcgisUserPrivilege: buildArcgisUserPrivilegeThenLoader[Q](),
CommsEmail: buildCommsEmailThenLoader[Q](),
CommsEmailLog: buildCommsEmailLogThenLoader[Q](),
CommsPhone: buildCommsPhoneThenLoader[Q](),
CommsSMSLog: buildCommsSMSLogThenLoader[Q](),
FieldseekerContainerrelate: buildFieldseekerContainerrelateThenLoader[Q](),
FieldseekerFieldscoutinglog: buildFieldseekerFieldscoutinglogThenLoader[Q](),
FieldseekerHabitatrelate: buildFieldseekerHabitatrelateThenLoader[Q](),

View file

@ -19,6 +19,10 @@ var (
func Where[Q psql.Filterable]() struct {
ArcgisUsers arcgisuserWhere[Q]
ArcgisUserPrivileges arcgisUserPrivilegeWhere[Q]
CommsEmails commsEmailWhere[Q]
CommsEmailLogs commsEmailLogWhere[Q]
CommsPhones commsPhoneWhere[Q]
CommsSMSLogs commsSMSLogWhere[Q]
FieldseekerContainerrelates fieldseekerContainerrelateWhere[Q]
FieldseekerFieldscoutinglogs fieldseekerFieldscoutinglogWhere[Q]
FieldseekerHabitatrelates fieldseekerHabitatrelateWhere[Q]
@ -78,6 +82,10 @@ func Where[Q psql.Filterable]() struct {
return struct {
ArcgisUsers arcgisuserWhere[Q]
ArcgisUserPrivileges arcgisUserPrivilegeWhere[Q]
CommsEmails commsEmailWhere[Q]
CommsEmailLogs commsEmailLogWhere[Q]
CommsPhones commsPhoneWhere[Q]
CommsSMSLogs commsSMSLogWhere[Q]
FieldseekerContainerrelates fieldseekerContainerrelateWhere[Q]
FieldseekerFieldscoutinglogs fieldseekerFieldscoutinglogWhere[Q]
FieldseekerHabitatrelates fieldseekerHabitatrelateWhere[Q]
@ -136,6 +144,10 @@ func Where[Q psql.Filterable]() struct {
}{
ArcgisUsers: buildArcgisUserWhere[Q](ArcgisUsers.Columns),
ArcgisUserPrivileges: buildArcgisUserPrivilegeWhere[Q](ArcgisUserPrivileges.Columns),
CommsEmails: buildCommsEmailWhere[Q](CommsEmails.Columns),
CommsEmailLogs: buildCommsEmailLogWhere[Q](CommsEmailLogs.Columns),
CommsPhones: buildCommsPhoneWhere[Q](CommsPhones.Columns),
CommsSMSLogs: buildCommsSMSLogWhere[Q](CommsSMSLogs.Columns),
FieldseekerContainerrelates: buildFieldseekerContainerrelateWhere[Q](FieldseekerContainerrelates.Columns),
FieldseekerFieldscoutinglogs: buildFieldseekerFieldscoutinglogWhere[Q](FieldseekerFieldscoutinglogs.Columns),
FieldseekerHabitatrelates: buildFieldseekerHabitatrelateWhere[Q](FieldseekerHabitatrelates.Columns),

View file

@ -0,0 +1,737 @@
// 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,848 @@
// 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/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"
)
// 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.CommsEmailmessagetype `db:"type,pk" `
R commsEmailLogR `db:"-" `
}
// CommsEmailLogSlice is an alias for a slice of pointers to CommsEmailLog.
// This should almost always be used instead of []*CommsEmailLog.
type CommsEmailLogSlice []*CommsEmailLog
// CommsEmailLogs contains methods to work with the email_log table
var CommsEmailLogs = psql.NewTablex[*CommsEmailLog, CommsEmailLogSlice, *CommsEmailLogSetter]("comms", "email_log", buildCommsEmailLogColumns("comms.email_log"))
// CommsEmailLogsQuery is a query on the email_log table
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
}
func buildCommsEmailLogColumns(alias string) commsEmailLogColumns {
return commsEmailLogColumns{
ColumnsExpr: expr.NewColumnsExpr(
"created", "destination", "source", "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"),
}
}
type commsEmailLogColumns struct {
expr.ColumnsExpr
tableAlias string
Created psql.Expression
Destination psql.Expression
Source psql.Expression
Type psql.Expression
}
func (c commsEmailLogColumns) Alias() string {
return c.tableAlias
}
func (commsEmailLogColumns) AliasedAs(alias string) commsEmailLogColumns {
return buildCommsEmailLogColumns(alias)
}
// CommsEmailLogSetter is used for insert/upsert/update operations
// 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.CommsEmailmessagetype] `db:"type,pk" `
}
func (s CommsEmailLogSetter) SetColumns() []string {
vals := make([]string, 0, 4)
if s.Created.IsValue() {
vals = append(vals, "created")
}
if s.Destination.IsValue() {
vals = append(vals, "destination")
}
if s.Source.IsValue() {
vals = append(vals, "source")
}
if s.Type.IsValue() {
vals = append(vals, "type")
}
return vals
}
func (s CommsEmailLogSetter) Overwrite(t *CommsEmailLog) {
if s.Created.IsValue() {
t.Created = s.Created.MustGet()
}
if s.Destination.IsValue() {
t.Destination = s.Destination.MustGet()
}
if s.Source.IsValue() {
t.Source = s.Source.MustGet()
}
if s.Type.IsValue() {
t.Type = s.Type.MustGet()
}
}
func (s *CommsEmailLogSetter) Apply(q *dialect.InsertQuery) {
q.AppendHooks(func(ctx context.Context, exec bob.Executor) (context.Context, error) {
return CommsEmailLogs.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.Created.IsValue() {
vals[0] = psql.Arg(s.Created.MustGet())
} else {
vals[0] = psql.Raw("DEFAULT")
}
if s.Destination.IsValue() {
vals[1] = psql.Arg(s.Destination.MustGet())
} else {
vals[1] = psql.Raw("DEFAULT")
}
if s.Source.IsValue() {
vals[2] = psql.Arg(s.Source.MustGet())
} else {
vals[2] = psql.Raw("DEFAULT")
}
if s.Type.IsValue() {
vals[3] = psql.Arg(s.Type.MustGet())
} else {
vals[3] = psql.Raw("DEFAULT")
}
return bob.ExpressSlice(ctx, w, d, start, vals, "", ", ", "")
}))
}
func (s CommsEmailLogSetter) UpdateMod() bob.Mod[*dialect.UpdateQuery] {
return um.Set(s.Expressions()...)
}
func (s CommsEmailLogSetter) Expressions(prefix ...string) []bob.Expression {
exprs := make([]bob.Expression, 0, 4)
if s.Created.IsValue() {
exprs = append(exprs, expr.Join{Sep: " = ", Exprs: []bob.Expression{
psql.Quote(append(prefix, "created")...),
psql.Arg(s.Created),
}})
}
if s.Destination.IsValue() {
exprs = append(exprs, expr.Join{Sep: " = ", Exprs: []bob.Expression{
psql.Quote(append(prefix, "destination")...),
psql.Arg(s.Destination),
}})
}
if s.Source.IsValue() {
exprs = append(exprs, expr.Join{Sep: " = ", Exprs: []bob.Expression{
psql.Quote(append(prefix, "source")...),
psql.Arg(s.Source),
}})
}
if s.Type.IsValue() {
exprs = append(exprs, expr.Join{Sep: " = ", Exprs: []bob.Expression{
psql.Quote(append(prefix, "type")...),
psql.Arg(s.Type),
}})
}
return exprs
}
// 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.CommsEmailmessagetype, 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))),
).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.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.CommsEmailmessagetype) (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))),
).Exists(ctx, exec)
}
// AfterQueryHook is called after CommsEmailLog is retrieved from the database
func (o *CommsEmailLog) AfterQueryHook(ctx context.Context, exec bob.Executor, queryType bob.QueryType) error {
var err error
switch queryType {
case bob.QueryTypeSelect:
ctx, err = CommsEmailLogs.AfterSelectHooks.RunHooks(ctx, exec, CommsEmailLogSlice{o})
case bob.QueryTypeInsert:
ctx, err = CommsEmailLogs.AfterInsertHooks.RunHooks(ctx, exec, CommsEmailLogSlice{o})
case bob.QueryTypeUpdate:
ctx, err = CommsEmailLogs.AfterUpdateHooks.RunHooks(ctx, exec, CommsEmailLogSlice{o})
case bob.QueryTypeDelete:
ctx, err = CommsEmailLogs.AfterDeleteHooks.RunHooks(ctx, exec, CommsEmailLogSlice{o})
}
return err
}
// primaryKeyVals returns the primary key values of the CommsEmailLog
func (o *CommsEmailLog) primaryKeyVals() bob.Expression {
return psql.ArgGroup(
o.Destination,
o.Source,
o.Type,
)
}
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 o.primaryKeyVals().WriteSQL(ctx, w, d, start)
}))
}
// Update uses an executor to update the CommsEmailLog
func (o *CommsEmailLog) Update(ctx context.Context, exec bob.Executor, s *CommsEmailLogSetter) error {
v, err := CommsEmailLogs.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 CommsEmailLog record with an executor
func (o *CommsEmailLog) Delete(ctx context.Context, exec bob.Executor) error {
_, err := CommsEmailLogs.Delete(dm.Where(o.pkEQ())).Exec(ctx, exec)
return err
}
// 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))),
).One(ctx, exec)
if err != nil {
return err
}
o2.R = o.R
*o = *o2
return nil
}
// AfterQueryHook is called after CommsEmailLogSlice is retrieved from the database
func (o CommsEmailLogSlice) AfterQueryHook(ctx context.Context, exec bob.Executor, queryType bob.QueryType) error {
var err error
switch queryType {
case bob.QueryTypeSelect:
ctx, err = CommsEmailLogs.AfterSelectHooks.RunHooks(ctx, exec, o)
case bob.QueryTypeInsert:
ctx, err = CommsEmailLogs.AfterInsertHooks.RunHooks(ctx, exec, o)
case bob.QueryTypeUpdate:
ctx, err = CommsEmailLogs.AfterUpdateHooks.RunHooks(ctx, exec, o)
case bob.QueryTypeDelete:
ctx, err = CommsEmailLogs.AfterDeleteHooks.RunHooks(ctx, exec, o)
}
return err
}
func (o CommsEmailLogSlice) pkIN() dialect.Expression {
if len(o) == 0 {
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) {
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 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 {
continue
}
new.R = old.R
o[i] = new
break
}
}
}
// UpdateMod modifies an update query with "WHERE primary_key IN (o...)"
func (o CommsEmailLogSlice) 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 CommsEmailLogs.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 *CommsEmailLog:
o.copyMatchingRows(retrieved)
case []*CommsEmailLog:
o.copyMatchingRows(retrieved...)
case CommsEmailLogSlice:
o.copyMatchingRows(retrieved...)
default:
// If the retrieved value is not a CommsEmailLog or a slice of CommsEmailLog
// then run the AfterUpdateHooks on the slice
_, err = CommsEmailLogs.AfterUpdateHooks.RunHooks(ctx, exec, o)
}
return err
}))
q.AppendWhere(o.pkIN())
})
}
// DeleteMod modifies an delete query with "WHERE primary_key IN (o...)"
func (o CommsEmailLogSlice) 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 CommsEmailLogs.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 *CommsEmailLog:
o.copyMatchingRows(retrieved)
case []*CommsEmailLog:
o.copyMatchingRows(retrieved...)
case CommsEmailLogSlice:
o.copyMatchingRows(retrieved...)
default:
// If the retrieved value is not a CommsEmailLog or a slice of CommsEmailLog
// then run the AfterDeleteHooks on the slice
_, err = CommsEmailLogs.AfterDeleteHooks.RunHooks(ctx, exec, o)
}
return err
}))
q.AppendWhere(o.pkIN())
})
}
func (o CommsEmailLogSlice) UpdateAll(ctx context.Context, exec bob.Executor, vals CommsEmailLogSetter) error {
if len(o) == 0 {
return nil
}
_, err := CommsEmailLogs.Update(vals.UpdateMod(), o.UpdateMod()).All(ctx, exec)
return err
}
func (o CommsEmailLogSlice) DeleteAll(ctx context.Context, exec bob.Executor) error {
if len(o) == 0 {
return nil
}
_, err := CommsEmailLogs.Delete(o.DeleteMod()).Exec(ctx, exec)
return err
}
func (o CommsEmailLogSlice) ReloadAll(ctx context.Context, exec bob.Executor) error {
if len(o) == 0 {
return nil
}
o2, err := CommsEmailLogs.Query(sm.Where(o.pkIN())).All(ctx, exec)
if err != nil {
return err
}
o.copyMatchingRows(o2...)
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))),
)...)
}
func (os CommsEmailLogSlice) DestinationEmail(mods ...bob.Mod[*dialect.SelectQuery]) CommsEmailsQuery {
pkDestination := make(pgtypes.Array[string], 0, len(os))
for _, o := range os {
if o == nil {
continue
}
pkDestination = append(pkDestination, o.Destination)
}
PKArgExpr := psql.Select(sm.Columns(
psql.F("unnest", psql.Cast(psql.Arg(pkDestination), "text[]")),
))
return CommsEmails.Query(append(mods,
sm.Where(psql.Group(CommsEmails.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))),
)...)
}
func (os CommsEmailLogSlice) SourcePhone(mods ...bob.Mod[*dialect.SelectQuery]) CommsPhonesQuery {
pkSource := make(pgtypes.Array[string], 0, len(os))
for _, o := range os {
if o == nil {
continue
}
pkSource = append(pkSource, o.Source)
}
PKArgExpr := psql.Select(sm.Columns(
psql.F("unnest", psql.Cast(psql.Arg(pkSource), "text[]")),
))
return CommsPhones.Query(append(mods,
sm.Where(psql.Group(CommsPhones.Columns.E164).OP("IN", PKArgExpr)),
)...)
}
func attachCommsEmailLogDestinationEmail0(ctx context.Context, exec bob.Executor, count int, commsEmailLog0 *CommsEmailLog, commsEmail1 *CommsEmail) (*CommsEmailLog, error) {
setter := &CommsEmailLogSetter{
Destination: omit.From(commsEmail1.Address),
}
err := commsEmailLog0.Update(ctx, exec, setter)
if err != nil {
return nil, fmt.Errorf("attachCommsEmailLogDestinationEmail0: %w", err)
}
return commsEmailLog0, nil
}
func (commsEmailLog0 *CommsEmailLog) InsertDestinationEmail(ctx context.Context, exec bob.Executor, related *CommsEmailSetter) error {
var err error
commsEmail1, err := CommsEmails.Insert(related).One(ctx, exec)
if err != nil {
return fmt.Errorf("inserting related objects: %w", err)
}
_, err = attachCommsEmailLogDestinationEmail0(ctx, exec, 1, commsEmailLog0, commsEmail1)
if err != nil {
return err
}
commsEmailLog0.R.DestinationEmail = commsEmail1
commsEmail1.R.DestinationEmailLogs = append(commsEmail1.R.DestinationEmailLogs, commsEmailLog0)
return nil
}
func (commsEmailLog0 *CommsEmailLog) AttachDestinationEmail(ctx context.Context, exec bob.Executor, commsEmail1 *CommsEmail) error {
var err error
_, err = attachCommsEmailLogDestinationEmail0(ctx, exec, 1, commsEmailLog0, commsEmail1)
if err != nil {
return err
}
commsEmailLog0.R.DestinationEmail = commsEmail1
commsEmail1.R.DestinationEmailLogs = append(commsEmail1.R.DestinationEmailLogs, commsEmailLog0)
return nil
}
func attachCommsEmailLogSourcePhone0(ctx context.Context, exec bob.Executor, count int, commsEmailLog0 *CommsEmailLog, commsPhone1 *CommsPhone) (*CommsEmailLog, error) {
setter := &CommsEmailLogSetter{
Source: omit.From(commsPhone1.E164),
}
err := commsEmailLog0.Update(ctx, exec, setter)
if err != nil {
return nil, fmt.Errorf("attachCommsEmailLogSourcePhone0: %w", err)
}
return commsEmailLog0, nil
}
func (commsEmailLog0 *CommsEmailLog) InsertSourcePhone(ctx context.Context, exec bob.Executor, related *CommsPhoneSetter) error {
var err error
commsPhone1, err := CommsPhones.Insert(related).One(ctx, exec)
if err != nil {
return fmt.Errorf("inserting related objects: %w", err)
}
_, err = attachCommsEmailLogSourcePhone0(ctx, exec, 1, commsEmailLog0, commsPhone1)
if err != nil {
return err
}
commsEmailLog0.R.SourcePhone = commsPhone1
commsPhone1.R.SourceEmailLogs = append(commsPhone1.R.SourceEmailLogs, commsEmailLog0)
return nil
}
func (commsEmailLog0 *CommsEmailLog) AttachSourcePhone(ctx context.Context, exec bob.Executor, commsPhone1 *CommsPhone) error {
var err error
_, err = attachCommsEmailLogSourcePhone0(ctx, exec, 1, commsEmailLog0, commsPhone1)
if err != nil {
return err
}
commsEmailLog0.R.SourcePhone = commsPhone1
commsPhone1.R.SourceEmailLogs = append(commsPhone1.R.SourceEmailLogs, 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.CommsEmailmessagetype]
}
func (commsEmailLogWhere[Q]) AliasedAs(alias string) commsEmailLogWhere[Q] {
return buildCommsEmailLogWhere[Q](buildCommsEmailLogColumns(alias))
}
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.CommsEmailmessagetype](cols.Type),
}
}
func (o *CommsEmailLog) Preload(name string, retrieved any) error {
if o == nil {
return nil
}
switch name {
case "DestinationEmail":
rel, ok := retrieved.(*CommsEmail)
if !ok {
return fmt.Errorf("commsEmailLog cannot load %T as %q", retrieved, name)
}
o.R.DestinationEmail = rel
if rel != nil {
rel.R.DestinationEmailLogs = CommsEmailLogSlice{o}
}
return nil
case "SourcePhone":
rel, ok := retrieved.(*CommsPhone)
if !ok {
return fmt.Errorf("commsEmailLog cannot load %T as %q", retrieved, name)
}
o.R.SourcePhone = rel
if rel != nil {
rel.R.SourceEmailLogs = CommsEmailLogSlice{o}
}
return nil
default:
return fmt.Errorf("commsEmailLog has no relationship %q", name)
}
}
type commsEmailLogPreloader struct {
DestinationEmail func(...psql.PreloadOption) psql.Preloader
SourcePhone 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",
Sides: []psql.PreloadSide{
{
From: CommsEmailLogs,
To: CommsEmails,
FromColumns: []string{"destination"},
ToColumns: []string{"address"},
},
},
}, CommsEmails.Columns.Names(), opts...)
},
SourcePhone: func(opts ...psql.PreloadOption) psql.Preloader {
return psql.Preload[*CommsPhone, CommsPhoneSlice](psql.PreloadRel{
Name: "SourcePhone",
Sides: []psql.PreloadSide{
{
From: CommsEmailLogs,
To: CommsPhones,
FromColumns: []string{"source"},
ToColumns: []string{"e164"},
},
},
}, CommsPhones.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]
}
func buildCommsEmailLogThenLoader[Q orm.Loadable]() commsEmailLogThenLoader[Q] {
type DestinationEmailLoadInterface interface {
LoadDestinationEmail(context.Context, bob.Executor, ...bob.Mod[*dialect.SelectQuery]) error
}
type SourcePhoneLoadInterface interface {
LoadSourcePhone(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...)
},
),
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...)
},
),
}
}
// 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 {
if o == nil {
return nil
}
// Reset the relationship
o.R.DestinationEmail = nil
related, err := o.DestinationEmail(mods...).One(ctx, exec)
if err != nil {
return err
}
related.R.DestinationEmailLogs = CommsEmailLogSlice{o}
o.R.DestinationEmail = 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 {
if len(os) == 0 {
return nil
}
commsEmails, err := os.DestinationEmail(mods...).All(ctx, exec)
if err != nil {
return err
}
for _, o := range os {
if o == nil {
continue
}
for _, rel := range commsEmails {
if !(o.Destination == rel.Address) {
continue
}
rel.R.DestinationEmailLogs = append(rel.R.DestinationEmailLogs, o)
o.R.DestinationEmail = rel
break
}
}
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 {
if o == nil {
return nil
}
// Reset the relationship
o.R.SourcePhone = nil
related, err := o.SourcePhone(mods...).One(ctx, exec)
if err != nil {
return err
}
related.R.SourceEmailLogs = CommsEmailLogSlice{o}
o.R.SourcePhone = 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 {
if len(os) == 0 {
return nil
}
commsPhones, err := os.SourcePhone(mods...).All(ctx, exec)
if err != nil {
return err
}
for _, o := range os {
if o == nil {
continue
}
for _, rel := range commsPhones {
if !(o.Source == rel.E164) {
continue
}
rel.R.SourceEmailLogs = append(rel.R.SourceEmailLogs, o)
o.R.SourcePhone = rel
break
}
}
return nil
}
type commsEmailLogJoins[Q dialect.Joinable] struct {
typ string
DestinationEmail modAs[Q, commsEmailColumns]
SourcePhone modAs[Q, commsPhoneColumns]
}
func (j commsEmailLogJoins[Q]) aliasedAs(alias string) commsEmailLogJoins[Q] {
return buildCommsEmailLogJoins[Q](buildCommsEmailLogColumns(alias), j.typ)
}
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] {
mods := make(mods.QueryMods[Q], 0, 1)
{
mods = append(mods, dialect.Join[Q](typ, CommsEmails.Name().As(to.Alias())).On(
to.Address.EQ(cols.Destination),
))
}
return mods
},
},
SourcePhone: modAs[Q, commsPhoneColumns]{
c: CommsPhones.Columns,
f: func(to commsPhoneColumns) 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),
))
}
return mods
},
},
}
}

1220
db/models/comms.phone.bob.go Normal file

File diff suppressed because it is too large Load diff

View file

@ -0,0 +1,848 @@
// 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/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"
)
// CommsSMSLog is an object representing the database table.
type CommsSMSLog struct {
Created time.Time `db:"created" `
Destination string `db:"destination,pk" `
Source string `db:"source,pk" `
Type enums.CommsSmsmessagetype `db:"type,pk" `
R commsSMSLogR `db:"-" `
}
// CommsSMSLogSlice is an alias for a slice of pointers to CommsSMSLog.
// This should almost always be used instead of []*CommsSMSLog.
type CommsSMSLogSlice []*CommsSMSLog
// CommsSMSLogs contains methods to work with the sms_log table
var CommsSMSLogs = psql.NewTablex[*CommsSMSLog, CommsSMSLogSlice, *CommsSMSLogSetter]("comms", "sms_log", buildCommsSMSLogColumns("comms.sms_log"))
// CommsSMSLogsQuery is a query on the sms_log table
type CommsSMSLogsQuery = *psql.ViewQuery[*CommsSMSLog, CommsSMSLogSlice]
// commsSMSLogR is where relationships are stored.
type commsSMSLogR struct {
DestinationPhone *CommsPhone // comms.sms_log.sms_log_destination_fkey
SourcePhone *CommsPhone // comms.sms_log.sms_log_source_fkey
}
func buildCommsSMSLogColumns(alias string) commsSMSLogColumns {
return commsSMSLogColumns{
ColumnsExpr: expr.NewColumnsExpr(
"created", "destination", "source", "type",
).WithParent("comms.sms_log"),
tableAlias: alias,
Created: psql.Quote(alias, "created"),
Destination: psql.Quote(alias, "destination"),
Source: psql.Quote(alias, "source"),
Type: psql.Quote(alias, "type"),
}
}
type commsSMSLogColumns struct {
expr.ColumnsExpr
tableAlias string
Created psql.Expression
Destination psql.Expression
Source psql.Expression
Type psql.Expression
}
func (c commsSMSLogColumns) Alias() string {
return c.tableAlias
}
func (commsSMSLogColumns) AliasedAs(alias string) commsSMSLogColumns {
return buildCommsSMSLogColumns(alias)
}
// CommsSMSLogSetter is used for insert/upsert/update operations
// All values are optional, and do not have to be set
// Generated columns are not included
type CommsSMSLogSetter 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.CommsSmsmessagetype] `db:"type,pk" `
}
func (s CommsSMSLogSetter) SetColumns() []string {
vals := make([]string, 0, 4)
if s.Created.IsValue() {
vals = append(vals, "created")
}
if s.Destination.IsValue() {
vals = append(vals, "destination")
}
if s.Source.IsValue() {
vals = append(vals, "source")
}
if s.Type.IsValue() {
vals = append(vals, "type")
}
return vals
}
func (s CommsSMSLogSetter) Overwrite(t *CommsSMSLog) {
if s.Created.IsValue() {
t.Created = s.Created.MustGet()
}
if s.Destination.IsValue() {
t.Destination = s.Destination.MustGet()
}
if s.Source.IsValue() {
t.Source = s.Source.MustGet()
}
if s.Type.IsValue() {
t.Type = s.Type.MustGet()
}
}
func (s *CommsSMSLogSetter) Apply(q *dialect.InsertQuery) {
q.AppendHooks(func(ctx context.Context, exec bob.Executor) (context.Context, error) {
return CommsSMSLogs.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.Created.IsValue() {
vals[0] = psql.Arg(s.Created.MustGet())
} else {
vals[0] = psql.Raw("DEFAULT")
}
if s.Destination.IsValue() {
vals[1] = psql.Arg(s.Destination.MustGet())
} else {
vals[1] = psql.Raw("DEFAULT")
}
if s.Source.IsValue() {
vals[2] = psql.Arg(s.Source.MustGet())
} else {
vals[2] = psql.Raw("DEFAULT")
}
if s.Type.IsValue() {
vals[3] = psql.Arg(s.Type.MustGet())
} else {
vals[3] = psql.Raw("DEFAULT")
}
return bob.ExpressSlice(ctx, w, d, start, vals, "", ", ", "")
}))
}
func (s CommsSMSLogSetter) UpdateMod() bob.Mod[*dialect.UpdateQuery] {
return um.Set(s.Expressions()...)
}
func (s CommsSMSLogSetter) Expressions(prefix ...string) []bob.Expression {
exprs := make([]bob.Expression, 0, 4)
if s.Created.IsValue() {
exprs = append(exprs, expr.Join{Sep: " = ", Exprs: []bob.Expression{
psql.Quote(append(prefix, "created")...),
psql.Arg(s.Created),
}})
}
if s.Destination.IsValue() {
exprs = append(exprs, expr.Join{Sep: " = ", Exprs: []bob.Expression{
psql.Quote(append(prefix, "destination")...),
psql.Arg(s.Destination),
}})
}
if s.Source.IsValue() {
exprs = append(exprs, expr.Join{Sep: " = ", Exprs: []bob.Expression{
psql.Quote(append(prefix, "source")...),
psql.Arg(s.Source),
}})
}
if s.Type.IsValue() {
exprs = append(exprs, expr.Join{Sep: " = ", Exprs: []bob.Expression{
psql.Quote(append(prefix, "type")...),
psql.Arg(s.Type),
}})
}
return exprs
}
// FindCommsSMSLog retrieves a single record by primary key
// If cols is empty Find will return all columns.
func FindCommsSMSLog(ctx context.Context, exec bob.Executor, DestinationPK string, SourcePK string, TypePK enums.CommsSmsmessagetype, cols ...string) (*CommsSMSLog, error) {
if len(cols) == 0 {
return CommsSMSLogs.Query(
sm.Where(CommsSMSLogs.Columns.Destination.EQ(psql.Arg(DestinationPK))),
sm.Where(CommsSMSLogs.Columns.Source.EQ(psql.Arg(SourcePK))),
sm.Where(CommsSMSLogs.Columns.Type.EQ(psql.Arg(TypePK))),
).One(ctx, exec)
}
return CommsSMSLogs.Query(
sm.Where(CommsSMSLogs.Columns.Destination.EQ(psql.Arg(DestinationPK))),
sm.Where(CommsSMSLogs.Columns.Source.EQ(psql.Arg(SourcePK))),
sm.Where(CommsSMSLogs.Columns.Type.EQ(psql.Arg(TypePK))),
sm.Columns(CommsSMSLogs.Columns.Only(cols...)),
).One(ctx, exec)
}
// CommsSMSLogExists checks the presence of a single record by primary key
func CommsSMSLogExists(ctx context.Context, exec bob.Executor, DestinationPK string, SourcePK string, TypePK enums.CommsSmsmessagetype) (bool, error) {
return CommsSMSLogs.Query(
sm.Where(CommsSMSLogs.Columns.Destination.EQ(psql.Arg(DestinationPK))),
sm.Where(CommsSMSLogs.Columns.Source.EQ(psql.Arg(SourcePK))),
sm.Where(CommsSMSLogs.Columns.Type.EQ(psql.Arg(TypePK))),
).Exists(ctx, exec)
}
// AfterQueryHook is called after CommsSMSLog is retrieved from the database
func (o *CommsSMSLog) AfterQueryHook(ctx context.Context, exec bob.Executor, queryType bob.QueryType) error {
var err error
switch queryType {
case bob.QueryTypeSelect:
ctx, err = CommsSMSLogs.AfterSelectHooks.RunHooks(ctx, exec, CommsSMSLogSlice{o})
case bob.QueryTypeInsert:
ctx, err = CommsSMSLogs.AfterInsertHooks.RunHooks(ctx, exec, CommsSMSLogSlice{o})
case bob.QueryTypeUpdate:
ctx, err = CommsSMSLogs.AfterUpdateHooks.RunHooks(ctx, exec, CommsSMSLogSlice{o})
case bob.QueryTypeDelete:
ctx, err = CommsSMSLogs.AfterDeleteHooks.RunHooks(ctx, exec, CommsSMSLogSlice{o})
}
return err
}
// primaryKeyVals returns the primary key values of the CommsSMSLog
func (o *CommsSMSLog) primaryKeyVals() bob.Expression {
return psql.ArgGroup(
o.Destination,
o.Source,
o.Type,
)
}
func (o *CommsSMSLog) pkEQ() dialect.Expression {
return psql.Group(psql.Quote("comms.sms_log", "destination"), psql.Quote("comms.sms_log", "source"), psql.Quote("comms.sms_log", "type")).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 CommsSMSLog
func (o *CommsSMSLog) Update(ctx context.Context, exec bob.Executor, s *CommsSMSLogSetter) error {
v, err := CommsSMSLogs.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 CommsSMSLog record with an executor
func (o *CommsSMSLog) Delete(ctx context.Context, exec bob.Executor) error {
_, err := CommsSMSLogs.Delete(dm.Where(o.pkEQ())).Exec(ctx, exec)
return err
}
// Reload refreshes the CommsSMSLog using the executor
func (o *CommsSMSLog) Reload(ctx context.Context, exec bob.Executor) error {
o2, err := CommsSMSLogs.Query(
sm.Where(CommsSMSLogs.Columns.Destination.EQ(psql.Arg(o.Destination))),
sm.Where(CommsSMSLogs.Columns.Source.EQ(psql.Arg(o.Source))),
sm.Where(CommsSMSLogs.Columns.Type.EQ(psql.Arg(o.Type))),
).One(ctx, exec)
if err != nil {
return err
}
o2.R = o.R
*o = *o2
return nil
}
// AfterQueryHook is called after CommsSMSLogSlice is retrieved from the database
func (o CommsSMSLogSlice) AfterQueryHook(ctx context.Context, exec bob.Executor, queryType bob.QueryType) error {
var err error
switch queryType {
case bob.QueryTypeSelect:
ctx, err = CommsSMSLogs.AfterSelectHooks.RunHooks(ctx, exec, o)
case bob.QueryTypeInsert:
ctx, err = CommsSMSLogs.AfterInsertHooks.RunHooks(ctx, exec, o)
case bob.QueryTypeUpdate:
ctx, err = CommsSMSLogs.AfterUpdateHooks.RunHooks(ctx, exec, o)
case bob.QueryTypeDelete:
ctx, err = CommsSMSLogs.AfterDeleteHooks.RunHooks(ctx, exec, o)
}
return err
}
func (o CommsSMSLogSlice) pkIN() dialect.Expression {
if len(o) == 0 {
return psql.Raw("NULL")
}
return psql.Group(psql.Quote("comms.sms_log", "destination"), psql.Quote("comms.sms_log", "source"), psql.Quote("comms.sms_log", "type")).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 CommsSMSLogSlice) copyMatchingRows(from ...*CommsSMSLog) {
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 {
continue
}
new.R = old.R
o[i] = new
break
}
}
}
// UpdateMod modifies an update query with "WHERE primary_key IN (o...)"
func (o CommsSMSLogSlice) 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 CommsSMSLogs.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 *CommsSMSLog:
o.copyMatchingRows(retrieved)
case []*CommsSMSLog:
o.copyMatchingRows(retrieved...)
case CommsSMSLogSlice:
o.copyMatchingRows(retrieved...)
default:
// If the retrieved value is not a CommsSMSLog or a slice of CommsSMSLog
// then run the AfterUpdateHooks on the slice
_, err = CommsSMSLogs.AfterUpdateHooks.RunHooks(ctx, exec, o)
}
return err
}))
q.AppendWhere(o.pkIN())
})
}
// DeleteMod modifies an delete query with "WHERE primary_key IN (o...)"
func (o CommsSMSLogSlice) 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 CommsSMSLogs.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 *CommsSMSLog:
o.copyMatchingRows(retrieved)
case []*CommsSMSLog:
o.copyMatchingRows(retrieved...)
case CommsSMSLogSlice:
o.copyMatchingRows(retrieved...)
default:
// If the retrieved value is not a CommsSMSLog or a slice of CommsSMSLog
// then run the AfterDeleteHooks on the slice
_, err = CommsSMSLogs.AfterDeleteHooks.RunHooks(ctx, exec, o)
}
return err
}))
q.AppendWhere(o.pkIN())
})
}
func (o CommsSMSLogSlice) UpdateAll(ctx context.Context, exec bob.Executor, vals CommsSMSLogSetter) error {
if len(o) == 0 {
return nil
}
_, err := CommsSMSLogs.Update(vals.UpdateMod(), o.UpdateMod()).All(ctx, exec)
return err
}
func (o CommsSMSLogSlice) DeleteAll(ctx context.Context, exec bob.Executor) error {
if len(o) == 0 {
return nil
}
_, err := CommsSMSLogs.Delete(o.DeleteMod()).Exec(ctx, exec)
return err
}
func (o CommsSMSLogSlice) ReloadAll(ctx context.Context, exec bob.Executor) error {
if len(o) == 0 {
return nil
}
o2, err := CommsSMSLogs.Query(sm.Where(o.pkIN())).All(ctx, exec)
if err != nil {
return err
}
o.copyMatchingRows(o2...)
return nil
}
// DestinationPhone starts a query for related objects on comms.phone
func (o *CommsSMSLog) DestinationPhone(mods ...bob.Mod[*dialect.SelectQuery]) CommsPhonesQuery {
return CommsPhones.Query(append(mods,
sm.Where(CommsPhones.Columns.E164.EQ(psql.Arg(o.Destination))),
)...)
}
func (os CommsSMSLogSlice) DestinationPhone(mods ...bob.Mod[*dialect.SelectQuery]) CommsPhonesQuery {
pkDestination := make(pgtypes.Array[string], 0, len(os))
for _, o := range os {
if o == nil {
continue
}
pkDestination = append(pkDestination, o.Destination)
}
PKArgExpr := psql.Select(sm.Columns(
psql.F("unnest", psql.Cast(psql.Arg(pkDestination), "text[]")),
))
return CommsPhones.Query(append(mods,
sm.Where(psql.Group(CommsPhones.Columns.E164).OP("IN", PKArgExpr)),
)...)
}
// SourcePhone starts a query for related objects on comms.phone
func (o *CommsSMSLog) SourcePhone(mods ...bob.Mod[*dialect.SelectQuery]) CommsPhonesQuery {
return CommsPhones.Query(append(mods,
sm.Where(CommsPhones.Columns.E164.EQ(psql.Arg(o.Source))),
)...)
}
func (os CommsSMSLogSlice) SourcePhone(mods ...bob.Mod[*dialect.SelectQuery]) CommsPhonesQuery {
pkSource := make(pgtypes.Array[string], 0, len(os))
for _, o := range os {
if o == nil {
continue
}
pkSource = append(pkSource, o.Source)
}
PKArgExpr := psql.Select(sm.Columns(
psql.F("unnest", psql.Cast(psql.Arg(pkSource), "text[]")),
))
return CommsPhones.Query(append(mods,
sm.Where(psql.Group(CommsPhones.Columns.E164).OP("IN", PKArgExpr)),
)...)
}
func attachCommsSMSLogDestinationPhone0(ctx context.Context, exec bob.Executor, count int, commsSMSLog0 *CommsSMSLog, commsPhone1 *CommsPhone) (*CommsSMSLog, error) {
setter := &CommsSMSLogSetter{
Destination: omit.From(commsPhone1.E164),
}
err := commsSMSLog0.Update(ctx, exec, setter)
if err != nil {
return nil, fmt.Errorf("attachCommsSMSLogDestinationPhone0: %w", err)
}
return commsSMSLog0, nil
}
func (commsSMSLog0 *CommsSMSLog) InsertDestinationPhone(ctx context.Context, exec bob.Executor, related *CommsPhoneSetter) error {
var err error
commsPhone1, err := CommsPhones.Insert(related).One(ctx, exec)
if err != nil {
return fmt.Errorf("inserting related objects: %w", err)
}
_, err = attachCommsSMSLogDestinationPhone0(ctx, exec, 1, commsSMSLog0, commsPhone1)
if err != nil {
return err
}
commsSMSLog0.R.DestinationPhone = commsPhone1
commsPhone1.R.DestinationSMSLogs = append(commsPhone1.R.DestinationSMSLogs, commsSMSLog0)
return nil
}
func (commsSMSLog0 *CommsSMSLog) AttachDestinationPhone(ctx context.Context, exec bob.Executor, commsPhone1 *CommsPhone) error {
var err error
_, err = attachCommsSMSLogDestinationPhone0(ctx, exec, 1, commsSMSLog0, commsPhone1)
if err != nil {
return err
}
commsSMSLog0.R.DestinationPhone = commsPhone1
commsPhone1.R.DestinationSMSLogs = append(commsPhone1.R.DestinationSMSLogs, commsSMSLog0)
return nil
}
func attachCommsSMSLogSourcePhone0(ctx context.Context, exec bob.Executor, count int, commsSMSLog0 *CommsSMSLog, commsPhone1 *CommsPhone) (*CommsSMSLog, error) {
setter := &CommsSMSLogSetter{
Source: omit.From(commsPhone1.E164),
}
err := commsSMSLog0.Update(ctx, exec, setter)
if err != nil {
return nil, fmt.Errorf("attachCommsSMSLogSourcePhone0: %w", err)
}
return commsSMSLog0, nil
}
func (commsSMSLog0 *CommsSMSLog) InsertSourcePhone(ctx context.Context, exec bob.Executor, related *CommsPhoneSetter) error {
var err error
commsPhone1, err := CommsPhones.Insert(related).One(ctx, exec)
if err != nil {
return fmt.Errorf("inserting related objects: %w", err)
}
_, err = attachCommsSMSLogSourcePhone0(ctx, exec, 1, commsSMSLog0, commsPhone1)
if err != nil {
return err
}
commsSMSLog0.R.SourcePhone = commsPhone1
commsPhone1.R.SourceSMSLogs = append(commsPhone1.R.SourceSMSLogs, commsSMSLog0)
return nil
}
func (commsSMSLog0 *CommsSMSLog) AttachSourcePhone(ctx context.Context, exec bob.Executor, commsPhone1 *CommsPhone) error {
var err error
_, err = attachCommsSMSLogSourcePhone0(ctx, exec, 1, commsSMSLog0, commsPhone1)
if err != nil {
return err
}
commsSMSLog0.R.SourcePhone = commsPhone1
commsPhone1.R.SourceSMSLogs = append(commsPhone1.R.SourceSMSLogs, commsSMSLog0)
return nil
}
type commsSMSLogWhere[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.CommsSmsmessagetype]
}
func (commsSMSLogWhere[Q]) AliasedAs(alias string) commsSMSLogWhere[Q] {
return buildCommsSMSLogWhere[Q](buildCommsSMSLogColumns(alias))
}
func buildCommsSMSLogWhere[Q psql.Filterable](cols commsSMSLogColumns) commsSMSLogWhere[Q] {
return commsSMSLogWhere[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.CommsSmsmessagetype](cols.Type),
}
}
func (o *CommsSMSLog) Preload(name string, retrieved any) error {
if o == nil {
return nil
}
switch name {
case "DestinationPhone":
rel, ok := retrieved.(*CommsPhone)
if !ok {
return fmt.Errorf("commsSMSLog cannot load %T as %q", retrieved, name)
}
o.R.DestinationPhone = rel
if rel != nil {
rel.R.DestinationSMSLogs = CommsSMSLogSlice{o}
}
return nil
case "SourcePhone":
rel, ok := retrieved.(*CommsPhone)
if !ok {
return fmt.Errorf("commsSMSLog cannot load %T as %q", retrieved, name)
}
o.R.SourcePhone = rel
if rel != nil {
rel.R.SourceSMSLogs = CommsSMSLogSlice{o}
}
return nil
default:
return fmt.Errorf("commsSMSLog has no relationship %q", name)
}
}
type commsSMSLogPreloader struct {
DestinationPhone func(...psql.PreloadOption) psql.Preloader
SourcePhone func(...psql.PreloadOption) psql.Preloader
}
func buildCommsSMSLogPreloader() commsSMSLogPreloader {
return commsSMSLogPreloader{
DestinationPhone: func(opts ...psql.PreloadOption) psql.Preloader {
return psql.Preload[*CommsPhone, CommsPhoneSlice](psql.PreloadRel{
Name: "DestinationPhone",
Sides: []psql.PreloadSide{
{
From: CommsSMSLogs,
To: CommsPhones,
FromColumns: []string{"destination"},
ToColumns: []string{"e164"},
},
},
}, CommsPhones.Columns.Names(), opts...)
},
SourcePhone: func(opts ...psql.PreloadOption) psql.Preloader {
return psql.Preload[*CommsPhone, CommsPhoneSlice](psql.PreloadRel{
Name: "SourcePhone",
Sides: []psql.PreloadSide{
{
From: CommsSMSLogs,
To: CommsPhones,
FromColumns: []string{"source"},
ToColumns: []string{"e164"},
},
},
}, CommsPhones.Columns.Names(), opts...)
},
}
}
type commsSMSLogThenLoader[Q orm.Loadable] struct {
DestinationPhone func(...bob.Mod[*dialect.SelectQuery]) orm.Loader[Q]
SourcePhone func(...bob.Mod[*dialect.SelectQuery]) orm.Loader[Q]
}
func buildCommsSMSLogThenLoader[Q orm.Loadable]() commsSMSLogThenLoader[Q] {
type DestinationPhoneLoadInterface interface {
LoadDestinationPhone(context.Context, bob.Executor, ...bob.Mod[*dialect.SelectQuery]) error
}
type SourcePhoneLoadInterface interface {
LoadSourcePhone(context.Context, bob.Executor, ...bob.Mod[*dialect.SelectQuery]) error
}
return commsSMSLogThenLoader[Q]{
DestinationPhone: thenLoadBuilder[Q](
"DestinationPhone",
func(ctx context.Context, exec bob.Executor, retrieved DestinationPhoneLoadInterface, mods ...bob.Mod[*dialect.SelectQuery]) error {
return retrieved.LoadDestinationPhone(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...)
},
),
}
}
// LoadDestinationPhone loads the commsSMSLog's DestinationPhone into the .R struct
func (o *CommsSMSLog) LoadDestinationPhone(ctx context.Context, exec bob.Executor, mods ...bob.Mod[*dialect.SelectQuery]) error {
if o == nil {
return nil
}
// Reset the relationship
o.R.DestinationPhone = nil
related, err := o.DestinationPhone(mods...).One(ctx, exec)
if err != nil {
return err
}
related.R.DestinationSMSLogs = CommsSMSLogSlice{o}
o.R.DestinationPhone = related
return nil
}
// LoadDestinationPhone loads the commsSMSLog's DestinationPhone into the .R struct
func (os CommsSMSLogSlice) LoadDestinationPhone(ctx context.Context, exec bob.Executor, mods ...bob.Mod[*dialect.SelectQuery]) error {
if len(os) == 0 {
return nil
}
commsPhones, err := os.DestinationPhone(mods...).All(ctx, exec)
if err != nil {
return err
}
for _, o := range os {
if o == nil {
continue
}
for _, rel := range commsPhones {
if !(o.Destination == rel.E164) {
continue
}
rel.R.DestinationSMSLogs = append(rel.R.DestinationSMSLogs, o)
o.R.DestinationPhone = rel
break
}
}
return nil
}
// LoadSourcePhone loads the commsSMSLog's SourcePhone into the .R struct
func (o *CommsSMSLog) LoadSourcePhone(ctx context.Context, exec bob.Executor, mods ...bob.Mod[*dialect.SelectQuery]) error {
if o == nil {
return nil
}
// Reset the relationship
o.R.SourcePhone = nil
related, err := o.SourcePhone(mods...).One(ctx, exec)
if err != nil {
return err
}
related.R.SourceSMSLogs = CommsSMSLogSlice{o}
o.R.SourcePhone = related
return nil
}
// LoadSourcePhone loads the commsSMSLog's SourcePhone into the .R struct
func (os CommsSMSLogSlice) LoadSourcePhone(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)
if err != nil {
return err
}
for _, o := range os {
if o == nil {
continue
}
for _, rel := range commsPhones {
if !(o.Source == rel.E164) {
continue
}
rel.R.SourceSMSLogs = append(rel.R.SourceSMSLogs, o)
o.R.SourcePhone = rel
break
}
}
return nil
}
type commsSMSLogJoins[Q dialect.Joinable] struct {
typ string
DestinationPhone modAs[Q, commsPhoneColumns]
SourcePhone modAs[Q, commsPhoneColumns]
}
func (j commsSMSLogJoins[Q]) aliasedAs(alias string) commsSMSLogJoins[Q] {
return buildCommsSMSLogJoins[Q](buildCommsSMSLogColumns(alias), j.typ)
}
func buildCommsSMSLogJoins[Q dialect.Joinable](cols commsSMSLogColumns, typ string) commsSMSLogJoins[Q] {
return commsSMSLogJoins[Q]{
typ: typ,
DestinationPhone: modAs[Q, commsPhoneColumns]{
c: CommsPhones.Columns,
f: func(to commsPhoneColumns) 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.Destination),
))
}
return mods
},
},
SourcePhone: modAs[Q, commsPhoneColumns]{
c: CommsPhones.Columns,
f: func(to commsPhoneColumns) 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),
))
}
return mods
},
},
}
}

View file

@ -10,7 +10,9 @@ import (
"strconv"
"time"
"github.com/aarondl/opt/null"
"github.com/aarondl/opt/omit"
"github.com/aarondl/opt/omitnull"
"github.com/google/uuid"
"github.com/stephenafamo/bob"
"github.com/stephenafamo/bob/dialect/psql"
@ -27,14 +29,15 @@ import (
// PublicreportImage is an object representing the database table.
type PublicreportImage struct {
ID int32 `db:"id,pk" `
ContentType string `db:"content_type" `
Created time.Time `db:"created" `
ResolutionX int32 `db:"resolution_x" `
ResolutionY int32 `db:"resolution_y" `
StorageUUID uuid.UUID `db:"storage_uuid" `
StorageSize int64 `db:"storage_size" `
UploadedFilename string `db:"uploaded_filename" `
ID int32 `db:"id,pk" `
ContentType string `db:"content_type" `
Created time.Time `db:"created" `
Location null.Val[string] `db:"location" `
ResolutionX int32 `db:"resolution_x" `
ResolutionY int32 `db:"resolution_y" `
StorageUUID uuid.UUID `db:"storage_uuid" `
StorageSize int64 `db:"storage_size" `
UploadedFilename string `db:"uploaded_filename" `
R publicreportImageR `db:"-" `
@ -61,12 +64,13 @@ type publicreportImageR struct {
func buildPublicreportImageColumns(alias string) publicreportImageColumns {
return publicreportImageColumns{
ColumnsExpr: expr.NewColumnsExpr(
"id", "content_type", "created", "resolution_x", "resolution_y", "storage_uuid", "storage_size", "uploaded_filename",
"id", "content_type", "created", "location", "resolution_x", "resolution_y", "storage_uuid", "storage_size", "uploaded_filename",
).WithParent("publicreport.image"),
tableAlias: alias,
ID: psql.Quote(alias, "id"),
ContentType: psql.Quote(alias, "content_type"),
Created: psql.Quote(alias, "created"),
Location: psql.Quote(alias, "location"),
ResolutionX: psql.Quote(alias, "resolution_x"),
ResolutionY: psql.Quote(alias, "resolution_y"),
StorageUUID: psql.Quote(alias, "storage_uuid"),
@ -81,6 +85,7 @@ type publicreportImageColumns struct {
ID psql.Expression
ContentType psql.Expression
Created psql.Expression
Location psql.Expression
ResolutionX psql.Expression
ResolutionY psql.Expression
StorageUUID psql.Expression
@ -100,18 +105,19 @@ func (publicreportImageColumns) AliasedAs(alias string) publicreportImageColumns
// All values are optional, and do not have to be set
// Generated columns are not included
type PublicreportImageSetter struct {
ID omit.Val[int32] `db:"id,pk" `
ContentType omit.Val[string] `db:"content_type" `
Created omit.Val[time.Time] `db:"created" `
ResolutionX omit.Val[int32] `db:"resolution_x" `
ResolutionY omit.Val[int32] `db:"resolution_y" `
StorageUUID omit.Val[uuid.UUID] `db:"storage_uuid" `
StorageSize omit.Val[int64] `db:"storage_size" `
UploadedFilename omit.Val[string] `db:"uploaded_filename" `
ID omit.Val[int32] `db:"id,pk" `
ContentType omit.Val[string] `db:"content_type" `
Created omit.Val[time.Time] `db:"created" `
Location omitnull.Val[string] `db:"location" `
ResolutionX omit.Val[int32] `db:"resolution_x" `
ResolutionY omit.Val[int32] `db:"resolution_y" `
StorageUUID omit.Val[uuid.UUID] `db:"storage_uuid" `
StorageSize omit.Val[int64] `db:"storage_size" `
UploadedFilename omit.Val[string] `db:"uploaded_filename" `
}
func (s PublicreportImageSetter) SetColumns() []string {
vals := make([]string, 0, 8)
vals := make([]string, 0, 9)
if s.ID.IsValue() {
vals = append(vals, "id")
}
@ -121,6 +127,9 @@ func (s PublicreportImageSetter) SetColumns() []string {
if s.Created.IsValue() {
vals = append(vals, "created")
}
if !s.Location.IsUnset() {
vals = append(vals, "location")
}
if s.ResolutionX.IsValue() {
vals = append(vals, "resolution_x")
}
@ -149,6 +158,9 @@ func (s PublicreportImageSetter) Overwrite(t *PublicreportImage) {
if s.Created.IsValue() {
t.Created = s.Created.MustGet()
}
if !s.Location.IsUnset() {
t.Location = s.Location.MustGetNull()
}
if s.ResolutionX.IsValue() {
t.ResolutionX = s.ResolutionX.MustGet()
}
@ -172,7 +184,7 @@ func (s *PublicreportImageSetter) 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, 8)
vals := make([]bob.Expression, 9)
if s.ID.IsValue() {
vals[0] = psql.Arg(s.ID.MustGet())
} else {
@ -191,36 +203,42 @@ func (s *PublicreportImageSetter) Apply(q *dialect.InsertQuery) {
vals[2] = psql.Raw("DEFAULT")
}
if s.ResolutionX.IsValue() {
vals[3] = psql.Arg(s.ResolutionX.MustGet())
if !s.Location.IsUnset() {
vals[3] = psql.Arg(s.Location.MustGetNull())
} else {
vals[3] = psql.Raw("DEFAULT")
}
if s.ResolutionY.IsValue() {
vals[4] = psql.Arg(s.ResolutionY.MustGet())
if s.ResolutionX.IsValue() {
vals[4] = psql.Arg(s.ResolutionX.MustGet())
} else {
vals[4] = psql.Raw("DEFAULT")
}
if s.StorageUUID.IsValue() {
vals[5] = psql.Arg(s.StorageUUID.MustGet())
if s.ResolutionY.IsValue() {
vals[5] = psql.Arg(s.ResolutionY.MustGet())
} else {
vals[5] = psql.Raw("DEFAULT")
}
if s.StorageSize.IsValue() {
vals[6] = psql.Arg(s.StorageSize.MustGet())
if s.StorageUUID.IsValue() {
vals[6] = psql.Arg(s.StorageUUID.MustGet())
} else {
vals[6] = psql.Raw("DEFAULT")
}
if s.UploadedFilename.IsValue() {
vals[7] = psql.Arg(s.UploadedFilename.MustGet())
if s.StorageSize.IsValue() {
vals[7] = psql.Arg(s.StorageSize.MustGet())
} else {
vals[7] = psql.Raw("DEFAULT")
}
if s.UploadedFilename.IsValue() {
vals[8] = psql.Arg(s.UploadedFilename.MustGet())
} else {
vals[8] = psql.Raw("DEFAULT")
}
return bob.ExpressSlice(ctx, w, d, start, vals, "", ", ", "")
}))
}
@ -230,7 +248,7 @@ func (s PublicreportImageSetter) UpdateMod() bob.Mod[*dialect.UpdateQuery] {
}
func (s PublicreportImageSetter) Expressions(prefix ...string) []bob.Expression {
exprs := make([]bob.Expression, 0, 8)
exprs := make([]bob.Expression, 0, 9)
if s.ID.IsValue() {
exprs = append(exprs, expr.Join{Sep: " = ", Exprs: []bob.Expression{
@ -253,6 +271,13 @@ func (s PublicreportImageSetter) Expressions(prefix ...string) []bob.Expression
}})
}
if !s.Location.IsUnset() {
exprs = append(exprs, expr.Join{Sep: " = ", Exprs: []bob.Expression{
psql.Quote(append(prefix, "location")...),
psql.Arg(s.Location),
}})
}
if s.ResolutionX.IsValue() {
exprs = append(exprs, expr.Join{Sep: " = ", Exprs: []bob.Expression{
psql.Quote(append(prefix, "resolution_x")...),
@ -798,6 +823,7 @@ type publicreportImageWhere[Q psql.Filterable] struct {
ID psql.WhereMod[Q, int32]
ContentType psql.WhereMod[Q, string]
Created psql.WhereMod[Q, time.Time]
Location psql.WhereNullMod[Q, string]
ResolutionX psql.WhereMod[Q, int32]
ResolutionY psql.WhereMod[Q, int32]
StorageUUID psql.WhereMod[Q, uuid.UUID]
@ -814,6 +840,7 @@ func buildPublicreportImageWhere[Q psql.Filterable](cols publicreportImageColumn
ID: psql.Where[Q, int32](cols.ID),
ContentType: psql.Where[Q, string](cols.ContentType),
Created: psql.Where[Q, time.Time](cols.Created),
Location: psql.WhereNull[Q, string](cols.Location),
ResolutionX: psql.Where[Q, int32](cols.ResolutionX),
ResolutionY: psql.Where[Q, int32](cols.ResolutionY),
StorageUUID: psql.Where[Q, uuid.UUID](cols.StorageUUID),

Binary file not shown.

After

Width:  |  Height:  |  Size: 32 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 48 KiB

16
main.go
View file

@ -65,6 +65,9 @@ func main() {
defer cancel()
background.NewOAuthTokenChannel = make(chan struct{}, 10)
queue.ChannelJobAudio = make(chan queue.JobAudio, 100) // Buffered channel to prevent blocking
queue.ChannelJobEmail = make(chan queue.JobEmail, 100) // Buffered channel to prevent blocking
queue.ChannelJobSMS = make(chan queue.JobSMS, 100) // Buffered channel to prevent blocking
var waitGroup sync.WaitGroup
@ -77,9 +80,20 @@ func main() {
waitGroup.Add(1)
go func() {
defer waitGroup.Done()
queue.StartAudioWorker(ctx)
background.StartWorkerAudio(ctx, queue.ChannelJobAudio)
}()
waitGroup.Add(1)
go func() {
defer waitGroup.Done()
background.StartWorkerEmail(ctx, queue.ChannelJobEmail)
}()
waitGroup.Add(1)
go func() {
defer waitGroup.Done()
background.StartWorkerSMS(ctx, queue.ChannelJobSMS)
}()
server := &http.Server{
Addr: config.Bind,
Handler: r,

View file

@ -14,14 +14,22 @@ type ContextRegisterNotificationsComplete struct {
type ContextRoot struct{}
var (
RegisterNotificationsComplete = buildTemplate("register-notifications-complete", "base")
Root = buildTemplate("root", "base")
PrivacyT = buildTemplate("privacy", "base")
RootT = buildTemplate("root", "base")
TermsT = buildTemplate("terms", "base")
)
func getPrivacy(w http.ResponseWriter, r *http.Request) {
htmlpage.RenderOrError(
w,
PrivacyT,
ContextRoot{},
)
}
func getRoot(w http.ResponseWriter, r *http.Request) {
htmlpage.RenderOrError(
w,
Root,
RootT,
ContextRoot{},
)
}
@ -30,6 +38,13 @@ func getRobots(w http.ResponseWriter, r *http.Request) {
fmt.Fprint(w, "User-agent: *\n")
fmt.Fprint(w, "Allow: /\n")
}
func getTerms(w http.ResponseWriter, r *http.Request) {
htmlpage.RenderOrError(
w,
TermsT,
ContextRoot{},
)
}
// Respond with an error that is visible to the user
func respondError(w http.ResponseWriter, m string, e error, s int) {

View file

@ -10,9 +10,6 @@ import (
//go:embed template/*
var embeddedFiles embed.FS
//go:embed static/*
var EmbeddedStaticFS embed.FS
var components = [...]string{"footer", "photo-upload", "photo-upload-header"}
func buildTemplate(files ...string) *htmlpage.BuiltTemplate {

View file

@ -6,12 +6,13 @@ import (
"strconv"
"time"
"github.com/Gleipnir-Technology/nidus-sync/comms"
"github.com/Gleipnir-Technology/nidus-sync/config"
"github.com/Gleipnir-Technology/nidus-sync/db"
"github.com/Gleipnir-Technology/nidus-sync/db/enums"
"github.com/Gleipnir-Technology/nidus-sync/db/models"
"github.com/Gleipnir-Technology/nidus-sync/h3utils"
"github.com/Gleipnir-Technology/nidus-sync/htmlpage"
"github.com/Gleipnir-Technology/nidus-sync/queue"
"github.com/aarondl/opt/omit"
"github.com/aarondl/opt/omitnull"
"github.com/rs/zerolog/log"
@ -26,14 +27,15 @@ type ContextQuickSubmitComplete struct {
}
var (
Quick = buildTemplate("quick", "base")
QuickSubmitComplete = buildTemplate("quick-submit-complete", "base")
quickT = buildTemplate("quick", "base")
quickSubmitCompleteT = buildTemplate("quick-submit-complete", "base")
registerNotificationsCompleteT = buildTemplate("register-notifications-complete", "base")
)
func getQuick(w http.ResponseWriter, r *http.Request) {
htmlpage.RenderOrError(
w,
Quick,
quickT,
ContextQuick{},
)
}
@ -41,7 +43,7 @@ func getQuickSubmitComplete(w http.ResponseWriter, r *http.Request) {
report := r.URL.Query().Get("report")
htmlpage.RenderOrError(
w,
QuickSubmitComplete,
quickSubmitCompleteT,
ContextQuickSubmitComplete{
ReportID: report,
},
@ -51,7 +53,7 @@ func getRegisterNotificationsComplete(w http.ResponseWriter, r *http.Request) {
report := r.URL.Query().Get("report")
htmlpage.RenderOrError(
w,
RegisterNotificationsComplete,
registerNotificationsCompleteT,
ContextRegisterNotificationsComplete{
ReportID: report,
},
@ -181,16 +183,18 @@ func postRegisterNotifications(w http.ResponseWriter, r *http.Request) {
return
}
if email != "" {
err := comms.SendEmailReportConfirmation(email, report_id)
if err != nil {
log.Error().Err(err).Msg("Failed to send email")
}
queue.EnqueueJobEmail(queue.JobEmail{
Destination: email,
Source: config.ForwardEmailReportAddress,
Type: enums.CommsEmailmessagetypeReportSubscriptionConfirmation,
})
}
if phone != "" {
err := comms.SendSMS(phone, "testing 1 2 3")
if err != nil {
log.Error().Err(err).Msg("Failed to send SMS")
}
queue.EnqueueJobSMS(queue.JobSMS{
Destination: phone,
Source: config.VoipMSNumber,
Type: enums.CommsSmsmessagetypeReportSubscriptionConfirmation,
})
}
if rowcount == 0 {
http.Redirect(w, r, fmt.Sprintf("/error?code=no-rows-affected&report=%s", report_id), http.StatusFound)

View file

@ -8,6 +8,7 @@ import (
func Router() chi.Router {
r := chi.NewRouter()
r.Get("/", getRoot)
r.Get("/privacy", getPrivacy)
r.Get("/robots.txt", getRobots)
r.Get("/email/report/{report_id}/subscription-confirmation", getEmailReportSubscriptionConfirmation)
r.Get("/nuisance", getNuisance)
@ -24,6 +25,7 @@ func Router() chi.Router {
r.Get("/search", getSearch)
r.Get("/status", getStatus)
r.Get("/status/{report_id}", getStatusByID)
r.Get("/terms-of-service", getTerms)
htmlpage.AddStaticRoute(r, "/static")
return r
}

File diff suppressed because one or more lines are too long

File diff suppressed because one or more lines are too long

File diff suppressed because one or more lines are too long

View file

@ -0,0 +1,212 @@
{{template "base.html" .}}
{{define "title"}}Privacy Policy{{end}}
{{define "extraheader"}}
{{end}}
{{define "content"}}
<h1>Privacy Policy</h1>
<p>Last updated: January 20, 2026</p>
<p>This Privacy Policy describes Our policies and procedures on the collection, use and disclosure of Your information when You use the Service and tells You about Your privacy rights and how the law protects You.</p>
<p>We use Your Personal Data to provide and improve the Service. By using the Service, You agree to the collection and use of information in accordance with this Privacy Policy.</p>
<h2>Interpretation and Definitions</h2>
<h3>Interpretation</h3>
<p>The words whose initial letters are capitalized have meanings defined under the following conditions. The following definitions shall have the same meaning regardless of whether they appear in singular or in plural.</p>
<h3>Definitions</h3>
<p>For the purposes of this Privacy Policy:</p>
<ul>
<li>
<p><strong>Account</strong> means a unique account created for You to access our Service or parts of our Service.</p>
</li>
<li>
<p><strong>Affiliate</strong> means an entity that controls, is controlled by, or is under common control with a party, where &quot;control&quot; means ownership of 50% or more of the shares, equity interest or other securities entitled to vote for election of directors or other managing authority.</p>
</li>
<li>
<p><strong>Company</strong> (referred to as either &quot;the Company&quot;, &quot;We&quot;, &quot;Us&quot; or &quot;Our&quot; in this Privacy Policy) refers to Gleipnir Technology LLC, 2726 S Quinn Ave, Gilbert, AZ.</p>
</li>
<li>
<p><strong>Cookies</strong> are small files that are placed on Your computer, mobile device or any other device by a website, containing the details of Your browsing history on that website among its many uses.</p>
</li>
<li>
<p><strong>Country</strong> refers to: Arizona, United States</p>
</li>
<li>
<p><strong>Device</strong> means any device that can access the Service such as a computer, a cell phone or a digital tablet.</p>
</li>
<li>
<p><strong>Personal Data</strong> (or &quot;Personal Information&quot;) is any information that relates to an identified or identifiable individual.</p>
<p>We use &quot;Personal Data&quot; and &quot;Personal Information&quot; interchangeably unless a law uses a specific term.</p>
</li>
<li>
<p><strong>Service</strong> refers to the Website.</p>
</li>
<li>
<p><strong>Service Provider</strong> means any natural or legal person who processes the data on behalf of the Company. It refers to third-party companies or individuals employed by the Company to facilitate the Service, to provide the Service on behalf of the Company, to perform services related to the Service or to assist the Company in analyzing how the Service is used.</p>
</li>
<li>
<p><strong>Usage Data</strong> refers to data collected automatically, either generated by the use of the Service or from the Service infrastructure itself (for example, the duration of a page visit).</p>
</li>
<li>
<p><strong>Website</strong> refers to Report Mosquitoes Online, accessible from <a href="https://report.mosquitoes.online" rel="external nofollow noopener" target="_blank">https://report.mosquitoes.online</a>.</p>
</li>
<li>
<p><strong>You</strong> means the individual accessing or using the Service, or the company, or other legal entity on behalf of which such individual is accessing or using the Service, as applicable.</p>
</li>
</ul>
<h2>Collecting and Using Your Personal Data</h2>
<h3>Types of Data Collected</h3>
<h4>Personal Data</h4>
<p>While using Our Service, We may ask You to provide Us with certain personally identifiable information that can be used to contact or identify You. Personally identifiable information may include, but is not limited to:</p>
<ul>
<li>Email address</li>
<li>First name and last name</li>
<li>Phone number</li>
<li>Address, State, Province, ZIP/Postal code, City</li>
</ul>
<h4>Usage Data</h4>
<p>Usage Data is collected automatically when using the Service.</p>
<p>Usage Data may include information such as Your Device's Internet Protocol address (e.g. IP address), browser type, browser version, the pages of our Service that You visit, the time and date of Your visit, the time spent on those pages, unique device identifiers and other diagnostic data.</p>
<p>When You access the Service by or through a mobile device, We may collect certain information automatically, including, but not limited to, the type of mobile device You use, Your mobile device's unique ID, the IP address of Your mobile device, Your mobile operating system, the type of mobile Internet browser You use, unique device identifiers and other diagnostic data.</p>
<p>We may also collect information that Your browser sends whenever You visit Our Service or when You access the Service by or through a mobile device.</p>
<h4>Tracking Technologies and Cookies</h4>
<p>We use Cookies and similar tracking technologies to track the activity on Our Service and store certain information. Tracking technologies We use include beacons, tags, and scripts to collect and track information and to improve and analyze Our Service. The technologies We use may include:</p>
<ul>
<li><strong>Cookies or Browser Cookies.</strong> A cookie is a small file placed on Your Device. You can instruct Your browser to refuse all Cookies or to indicate when a Cookie is being sent. However, if You do not accept Cookies, You may not be able to use some parts of our Service.</li>
</ul>
<p>Cookies can be &quot;Persistent&quot; or &quot;Session&quot; Cookies. Persistent Cookies remain on Your personal computer or mobile device when You go offline, while Session Cookies are deleted as soon as You close Your web browser.</p>
<p>Where required by law, we use non-essential cookies (such as analytics, advertising, and remarketing cookies) only with Your consent. You can withdraw or change Your consent at any time using Our cookie preferences tool (if available) or through Your browser/device settings. Withdrawing consent does not affect the lawfulness of processing based on consent before its withdrawal.</p>
<p>We use both Session and Persistent Cookies for the purposes set out below:</p>
<ul>
<li>
<p><strong>Necessary / Essential Cookies</strong></p>
<p>Type: Session Cookies</p>
<p>Administered by: Us</p>
<p>Purpose: These Cookies are essential to provide You with services available through the Website and to enable You to use some of its features. They help to authenticate users and prevent fraudulent use of user accounts. Without these Cookies, the services that You have asked for cannot be provided, and We only use these Cookies to provide You with those services.</p>
</li>
<li>
<p><strong>Functionality Cookies</strong></p>
<p>Type: Persistent Cookies</p>
<p>Administered by: Us</p>
<p>Purpose: These Cookies allow Us to remember choices You make when You use the Website, such as remembering your login details or language preference. The purpose of these Cookies is to provide You with a more personal experience and to avoid You having to re-enter your preferences every time You use the Website.</p>
</li>
</ul>
<p>For more information about the cookies we use and your choices regarding cookies, please visit our Cookies Policy or the Cookies section of Our Privacy Policy.</p>
<h3>Use of Your Personal Data</h3>
<p>The Company may use Personal Data for the following purposes:</p>
<ul>
<li>
<p><strong>To provide and maintain our Service</strong>, including to monitor the usage of our Service.</p>
</li>
<li>
<p><strong>To manage Your Account:</strong> to manage Your registration as a user of the Service. The Personal Data You provide can give You access to different functionalities of the Service that are available to You as a registered user.</p>
</li>
<li>
<p><strong>For the performance of a contract:</strong> the development, compliance and undertaking of the purchase contract for the products, items or services You have purchased or of any other contract with Us through the Service.</p>
</li>
<li>
<p><strong>To contact You:</strong> To contact You by email, telephone calls, SMS, or other equivalent forms of electronic communication, such as a mobile application's push notifications regarding updates or informative communications related to the functionalities, products or contracted services, including the security updates, when necessary or reasonable for their implementation.</p>
</li>
<li>
<p><strong>To provide You</strong> with news, special offers, and general information about other goods, services and events which We offer that are similar to those that you have already purchased or inquired about unless You have opted not to receive such information.</p>
</li>
<li>
<p><strong>To manage Your requests:</strong> To attend and manage Your requests to Us.</p>
</li>
<li>
<p><strong>For business transfers:</strong> We may use Your Personal Data to evaluate or conduct a merger, divestiture, restructuring, reorganization, dissolution, or other sale or transfer of some or all of Our assets, whether as a going concern or as part of bankruptcy, liquidation, or similar proceeding, in which Personal Data held by Us about our Service users is among the assets transferred.</p>
</li>
<li>
<p><strong>For other purposes</strong>: We may use Your information for other purposes, such as data analysis, identifying usage trends, determining the effectiveness of our promotional campaigns and to evaluate and improve our Service, products, services, marketing and your experience.</p>
</li>
</ul>
<p>We may share Your Personal Data in the following situations:</p>
<ul>
<li><strong>With Service Providers:</strong> We may share Your Personal Data with Service Providers to monitor and analyze the use of our Service, to contact You.</li>
<li><strong>For business transfers:</strong> We may share or transfer Your Personal Data in connection with, or during negotiations of, any merger, sale of Company assets, financing, or acquisition of all or a portion of Our business to another company.</li>
<li><strong>With Affiliates:</strong> We may share Your Personal Data with Our affiliates, in which case we will require those affiliates to honor this Privacy Policy. Affiliates include Our parent company and any other subsidiaries, joint venture partners or other companies that We control or that are under common control with Us.</li>
<li><strong>With business partners:</strong> We may share Your Personal Data with Our business partners to offer You certain products, services or promotions.</li>
<li><strong>With other users:</strong> If Our Service offers public areas, when You share Personal Data or otherwise interact in the public areas with other users, such information may be viewed by all users and may be publicly distributed outside.</li>
<li><strong>With Your consent</strong>: We may disclose Your Personal Data for any other purpose with Your consent.</li>
</ul>
<h3>Retention of Your Personal Data</h3>
<p>The Company will retain Your Personal Data only for as long as is necessary for the purposes set out in this Privacy Policy. We will retain and use Your Personal Data to the extent necessary to comply with our legal obligations (for example, if We are required to retain Your data to comply with applicable laws), resolve disputes, and enforce our legal agreements and policies.</p>
<p>Where possible, We apply shorter retention periods and/or reduce identifiability by deleting, aggregating, or anonymizing data. Unless otherwise stated, the retention periods below are maximum periods (&quot;up to&quot;) and We may delete or anonymize data sooner when it is no longer needed for the relevant purpose. We apply different retention periods to different categories of Personal Data based on the purpose of processing and legal obligations:</p>
<ul>
<li>
<p>Account Information</p>
<ul>
<li>User Accounts: retained for the duration of your account relationship plus up to 24 months after account closure to handle any post-termination issues or resolve disputes.</li>
</ul>
</li>
<li>
<p>Customer Support Data</p>
<ul>
<li>Support tickets and correspondence: up to 24 months from the date of ticket closure to resolve follow-up inquiries, track service quality, and defend against potential legal claims</li>
<li>Chat transcripts: up to 24 months for quality assurance and staff training purposes.</li>
</ul>
</li>
<li>
<p>Usage Data</p>
<ul>
<li>
<p>Website analytics data (cookies, IP addresses, device identifiers): up to 24 months from the date of collection, which allows us to analyze trends while respecting privacy principles.</p>
</li>
<li>
<p>Server logs (IP addresses, access times): up to 24 months for security monitoring and troubleshooting purposes.</p>
</li>
</ul>
</li>
</ul>
<p>Usage Data is retained in accordance with the retention periods described above, and may be retained longer only where necessary for security, fraud prevention, or legal compliance.</p>
<p>We may retain Personal Data beyond the periods stated above for different reasons:</p>
<ul>
<li>Legal obligation: We are required by law to retain specific data (e.g., financial records for tax authorities).</li>
<li>Legal claims: Data is necessary to establish, exercise, or defend legal claims.</li>
<li>Your explicit request: You ask Us to retain specific information.</li>
<li>Technical limitations: Data exists in backup systems that are scheduled for routine deletion.</li>
</ul>
<p>You may request information about how long We will retain Your Personal Data by contacting Us.</p>
<p>When retention periods expire, We securely delete or anonymize Personal Data according to the following procedures:</p>
<ul>
<li>Deletion: Personal Data is removed from Our systems and no longer actively processed.</li>
<li>Backup retention: Residual copies may remain in encrypted backups for a limited period consistent with our backup retention schedule and are not restored except where necessary for security, disaster recovery, or legal compliance.</li>
<li>Anonymization: In some cases, We convert Personal Data into anonymous statistical data that cannot be linked back to You. This anonymized data may be retained indefinitely for research and analytics.</li>
</ul>
<h3>Transfer of Your Personal Data</h3>
<p>Your information, including Personal Data, is processed at the Company's operating offices and in any other places where the parties involved in the processing are located. It means that this information may be transferred to — and maintained on — computers located outside of Your state, province, country or other governmental jurisdiction where the data protection laws may differ from those from Your jurisdiction.</p>
<p>Where required by applicable law, We will ensure that international transfers of Your Personal Data are subject to appropriate safeguards and supplementary measures where appropriate. The Company will take all steps reasonably necessary to ensure that Your data is treated securely and in accordance with this Privacy Policy and no transfer of Your Personal Data will take place to an organization or a country unless there are adequate controls in place including the security of Your data and other personal information.</p>
<h3>Delete Your Personal Data</h3>
<p>You have the right to delete or request that We assist in deleting the Personal Data that We have collected about You.</p>
<p>Our Service may give You the ability to delete certain information about You from within the Service.</p>
<p>You may update, amend, or delete Your information at any time by signing in to Your Account, if you have one, and visiting the account settings section that allows you to manage Your personal information. You may also contact Us to request access to, correct, or delete any Personal Data that You have provided to Us.</p>
<p>Please note, however, that We may need to retain certain information when we have a legal obligation or lawful basis to do so.</p>
<h3>Disclosure of Your Personal Data</h3>
<h4>Business Transactions</h4>
<p>If the Company is involved in a merger, acquisition or asset sale, Your Personal Data may be transferred. We will provide notice before Your Personal Data is transferred and becomes subject to a different Privacy Policy.</p>
<h4>Law enforcement</h4>
<p>Under certain circumstances, the Company may be required to disclose Your Personal Data if required to do so by law or in response to valid requests by public authorities (e.g. a court or a government agency).</p>
<h4>Other legal requirements</h4>
<p>The Company may disclose Your Personal Data in the good faith belief that such action is necessary to:</p>
<ul>
<li>Comply with a legal obligation</li>
<li>Protect and defend the rights or property of the Company</li>
<li>Prevent or investigate possible wrongdoing in connection with the Service</li>
<li>Protect the personal safety of Users of the Service or the public</li>
<li>Protect against legal liability</li>
</ul>
<h3>Security of Your Personal Data</h3>
<p>The security of Your Personal Data is important to Us, but remember that no method of transmission over the Internet, or method of electronic storage is 100% secure. While We strive to use commercially reasonable means to protect Your Personal Data, We cannot guarantee its absolute security.</p>
<h2>Children's Privacy</h2>
<p>Our Service does not address anyone under the age of 16. We do not knowingly collect personally identifiable information from anyone under the age of 16. If You are a parent or guardian and You are aware that Your child has provided Us with Personal Data, please contact Us. If We become aware that We have collected Personal Data from anyone under the age of 16 without verification of parental consent, We take steps to remove that information from Our servers.</p>
<p>If We need to rely on consent as a legal basis for processing Your information and Your country requires consent from a parent, We may require Your parent's consent before We collect and use that information.</p>
<h2>Links to Other Websites</h2>
<p>Our Service may contain links to other websites that are not operated by Us. If You click on a third party link, You will be directed to that third party's site. We strongly advise You to review the Privacy Policy of every site You visit.</p>
<p>We have no control over and assume no responsibility for the content, privacy policies or practices of any third party sites or services.</p>
<h2>Changes to this Privacy Policy</h2>
<p>We may update Our Privacy Policy from time to time. We will notify You of any changes by posting the new Privacy Policy on this page.</p>
<p>We will let You know via email and/or a prominent notice on Our Service, prior to the change becoming effective and update the &quot;Last updated&quot; date at the top of this Privacy Policy.</p>
<p>You are advised to review this Privacy Policy periodically for any changes. Changes to this Privacy Policy are effective when they are posted on this page.</p>
<h2>Contact Us</h2>
<p>If you have any questions about this Privacy Policy, You can contact us:</p>
<ul>
<li>By email: privacy@gleipnir.technology</li>
</ul>
{{end}}

View file

@ -0,0 +1,26 @@
{{template "base.html" .}}
{{define "title"}}Privacy Policy{{end}}
{{define "extraheader"}}
{{end}}
{{define "content"}}
<div class="container">
<h1>Terms of Service</h1>
<p>Look, we don't like having terms of service, and we're confident you don't find them interesting to read. But we have to have them as a business.</p>
<h2>Service provider</h2>
<p>Report Mosquitoes Online is provided by Gleipnir Technology LLC. By using the website you agree to these terms. If you don't agree, don't tell a computer to access our site.</p>
<p>Gleipnir Technology LLC is a company organized under the laws of the state of Arizona, USA, and operates under Arizona law.</p>
<p>Gleipnir Technology LLC is located at 2726 S Quinn Ave, Gilbert, AZ</p>
<h2>What you can expect from us</h2>
<p>We provide services free to the public. We'll occasionally make changes to these services. We won't notify members of the public, like you, of those changes. We may notify our customers, but we may not, since we may changes very frequently. In general, we have additional agreements beyond this one with entities that are our customers.</p>
<p>The data you provide to us is used for public health. That generally means passing some or all of your data on to our customers that work in mosquito abatement. Any information you give to us we may give to them. You can request at any time that we stop sharing your information and we will honor that request.</p>
<p>We will only contact you if you give us express permission to do so</p>
<p>We won't sell your information to marketers, data aggregators, or anyone who makes money off your data. We only share data with entities engaged in public health work.</p>
<p>We are so vehemently opposed to selling your data that we agree to a contractual obligation of at least $1000 USD in damages per person if your data is every sold by the Company, or by any company in the future that aquires a stake in the Company.</p>
<h2>What we expect from you</h2>
<p>Don't provide false data. This include shenanigans like using our system to send messages to other people's email address or phone.</p>
<p>Don't try to scrape/exfiltrate/steal our data. If you've got a legitimate use for our data, contact us, if you've got a worthy project we may be willing to work with you.</p>
<p>Don't try to break into our systems, infect them with malware, use us as a tool in a phishing campaign, or generally hack about. We like hackers, but we prefer to work with them intentionally.</p>
<p>Don't misrepresent who you are</p>
<p>You agree we can use any data you provide to us as we see fit. This may include doing nothing with it, but generally includes improving public health by fighting mosquitoes and mosquito-born illnesses.</p>
</div>
{{end}}

View file

@ -1,121 +1,23 @@
package queue
import (
"context"
"errors"
"fmt"
"os"
"os/exec"
"github.com/Gleipnir-Technology/nidus-sync/db"
"github.com/Gleipnir-Technology/nidus-sync/userfile"
"github.com/google/uuid"
"github.com/rs/zerolog/log"
)
// AudioJob represents a job to process an audio file.
type AudioJob struct {
type JobAudio struct {
AudioUUID uuid.UUID
}
// audioJobChannel is the channel used to send audio processing jobs to the worker.
var audioJobChannel chan AudioJob
// StartAudioWorker initializes the audio job channel and starts the worker goroutine.
func StartAudioWorker(ctx context.Context) {
buffer := 100
audioJobChannel = make(chan AudioJob, buffer) // Buffered channel to prevent blocking
log.Info().Int("buffer depth", buffer).Msg("Started audio worker")
go func() {
for {
select {
case <-ctx.Done():
log.Info().Msg("Audio worker shutting down.")
return
case job := <-audioJobChannel:
log.Info().Str("uuid", job.AudioUUID.String()).Msg("Processing audio job")
err := processAudioFile(job.AudioUUID)
if err != nil {
log.Error().Err(err).Str("uuid", job.AudioUUID.String()).Msg("Error processing audio file")
}
}
}
}()
}
var ChannelJobAudio chan JobAudio
// EnqueueAudioJob sends an audio processing job to the worker.
func EnqueueAudioJob(job AudioJob) {
func EnqueueAudioJob(job JobAudio) {
select {
case audioJobChannel <- job:
case ChannelJobAudio <- job:
log.Info().Str("uuid", job.AudioUUID.String()).Msg("Enqueued audio job")
default:
log.Warn().Str("uuid", job.AudioUUID.String()).Msg("Audio job channel is full, dropping job")
}
}
func processAudioFile(audioUUID uuid.UUID) error {
// Normalize audio
err := normalizeAudio(audioUUID)
if err != nil {
return fmt.Errorf("failed to normalize audio %s: %v", audioUUID, err)
}
// Transcode to OGG
err = transcodeToOgg(audioUUID)
if err != nil {
return fmt.Errorf("failed to transcode audio %s to OGG: %v", audioUUID, err)
}
EnqueueLabelStudioJob(LabelStudioJob{
UUID: audioUUID,
})
return nil
}
func normalizeAudio(audioUUID uuid.UUID) error {
source := userfile.AudioFileContentPathRaw(audioUUID.String())
_, err := os.Stat(source)
if errors.Is(err, os.ErrNotExist) {
log.Warn().Str("source", source).Msg("file doesn't exist, skipping normalization")
return nil
}
log.Info().Str("sourcce", source).Msg("Normalizing")
destination := userfile.AudioFileContentPathNormalized(audioUUID.String())
// Use "ffmpeg" directly, assuming it's in the system PATH
cmd := exec.Command("ffmpeg", "-i", source, "-filter:a", "loudnorm", destination)
out, err := cmd.CombinedOutput()
if err != nil {
log.Printf("FFmpeg output for normalization: %s", out)
return fmt.Errorf("ffmpeg normalization failed: %v", err)
}
err = db.NoteAudioNormalized(audioUUID.String())
if err != nil {
return fmt.Errorf("failed to update database for normalized audio %s: %v", audioUUID, err)
}
log.Info().Str("destination", destination).Msg("Normalized audio")
return nil
}
func transcodeToOgg(audioUUID uuid.UUID) error {
source := userfile.AudioFileContentPathNormalized(audioUUID.String())
_, err := os.Stat(source)
if errors.Is(err, os.ErrNotExist) {
log.Warn().Str("source", source).Msg("file doesn't exist, skipping OGG transcoding")
return nil
}
log.Info().Str("source", source).Msg("Transcoding to ogg")
destination := userfile.AudioFileContentPathOgg(audioUUID.String())
// Use "ffmpeg" directly, assuming it's in the system PATH
cmd := exec.Command("ffmpeg", "-i", source, "-vn", "-acodec", "libvorbis", destination)
out, err := cmd.CombinedOutput()
if err != nil {
log.Error().Err(err).Bytes("out", out).Msg("FFmpeg output for OGG transcoding")
return fmt.Errorf("ffmpeg OGG transcoding failed: %v", err)
}
err = db.NoteAudioTranscodedToOgg(audioUUID.String())
if err != nil {
return fmt.Errorf("failed to update database for OGG transcoded audio %s: %v", audioUUID, err)
}
log.Info().Str("destination", destination).Msg("Transcoded audio")
return nil
}

38
queue/comms.go Normal file
View file

@ -0,0 +1,38 @@
package queue
import (
"github.com/Gleipnir-Technology/nidus-sync/db/enums"
"github.com/rs/zerolog/log"
)
type JobEmail struct {
Destination string
Source string
Type enums.CommsEmailmessagetype
}
type JobSMS struct {
Destination string
Source string
Type enums.CommsSmsmessagetype
}
var ChannelJobEmail chan JobEmail
var ChannelJobSMS chan JobSMS
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 EnqueueJobSMS(job JobSMS) {
select {
case ChannelJobSMS <- job:
log.Info().Str("destination", job.Destination).Msg("Enqueued sms job")
default:
log.Warn().Msg("sms job channel is full, dropping job")
}
}