Save tags on pool rows, show errors in summary table

This commit is contained in:
Eli Ribble 2026-02-16 16:38:04 +00:00
parent 123a4bf590
commit ef569aef18
No known key found for this signature in database
11 changed files with 305 additions and 172 deletions

View file

@ -96,15 +96,6 @@ var FileuploadPools = Table[
Generated: false,
AutoIncr: false,
},
Geom: column{
Name: "geom",
DBType: "geometry",
Default: "NULL",
Comment: "",
Nullable: true,
Generated: false,
AutoIncr: false,
},
H3cell: column{
Name: "h3cell",
DBType: "h3index",
@ -204,6 +195,24 @@ var FileuploadPools = Table[
Generated: false,
AutoIncr: false,
},
Geom: column{
Name: "geom",
DBType: "geometry",
Default: "NULL",
Comment: "",
Nullable: true,
Generated: false,
AutoIncr: false,
},
Tags: column{
Name: "tags",
DBType: "hstore",
Default: "",
Comment: "",
Nullable: false,
Generated: false,
AutoIncr: false,
},
},
Indexes: fileuploadPoolIndexes{
PoolPkey: index{
@ -295,7 +304,6 @@ type fileuploadPoolColumns struct {
CreatorID column
CSVFile column
Deleted column
Geom column
H3cell column
ID column
IsInDistrict column
@ -307,11 +315,13 @@ type fileuploadPoolColumns struct {
Version column
PropertyOwnerPhoneE164 column
ResidentPhoneE164 column
Geom column
Tags column
}
func (c fileuploadPoolColumns) AsSlice() []column {
return []column{
c.AddressCity, c.AddressPostalCode, c.AddressStreet, c.Committed, c.Condition, c.Created, c.CreatorID, c.CSVFile, c.Deleted, c.Geom, c.H3cell, c.ID, c.IsInDistrict, c.IsNew, c.Notes, c.OrganizationID, c.PropertyOwnerName, c.ResidentOwned, c.Version, c.PropertyOwnerPhoneE164, c.ResidentPhoneE164,
c.AddressCity, c.AddressPostalCode, c.AddressStreet, c.Committed, c.Condition, c.Created, c.CreatorID, c.CSVFile, c.Deleted, c.H3cell, c.ID, c.IsInDistrict, c.IsNew, c.Notes, c.OrganizationID, c.PropertyOwnerName, c.ResidentOwned, c.Version, c.PropertyOwnerPhoneE164, c.ResidentPhoneE164, c.Geom, c.Tags,
}
}

View file

@ -2425,7 +2425,6 @@ func (f *Factory) FromExistingFileuploadPool(m *models.FileuploadPool) *Fileuplo
o.CreatorID = func() int32 { return m.CreatorID }
o.CSVFile = func() int32 { return m.CSVFile }
o.Deleted = func() null.Val[time.Time] { return m.Deleted }
o.Geom = func() null.Val[string] { return m.Geom }
o.H3cell = func() null.Val[string] { return m.H3cell }
o.ID = func() int32 { return m.ID }
o.IsInDistrict = func() bool { return m.IsInDistrict }
@ -2437,6 +2436,8 @@ func (f *Factory) FromExistingFileuploadPool(m *models.FileuploadPool) *Fileuplo
o.Version = func() int32 { return m.Version }
o.PropertyOwnerPhoneE164 = func() null.Val[string] { return m.PropertyOwnerPhoneE164 }
o.ResidentPhoneE164 = func() null.Val[string] { return m.ResidentPhoneE164 }
o.Geom = func() null.Val[string] { return m.Geom }
o.Tags = func() pgtypes.HStore { return m.Tags }
ctx := context.Background()
if m.R.CreatorUser != nil {

View file

@ -9,6 +9,7 @@ import (
"time"
"github.com/Gleipnir-Technology/bob"
"github.com/Gleipnir-Technology/bob/types/pgtypes"
enums "github.com/Gleipnir-Technology/nidus-sync/db/enums"
models "github.com/Gleipnir-Technology/nidus-sync/db/models"
"github.com/aarondl/opt/null"
@ -47,7 +48,6 @@ type FileuploadPoolTemplate struct {
CreatorID func() int32
CSVFile func() int32
Deleted func() null.Val[time.Time]
Geom func() null.Val[string]
H3cell func() null.Val[string]
ID func() int32
IsInDistrict func() bool
@ -59,6 +59,8 @@ type FileuploadPoolTemplate struct {
Version func() int32
PropertyOwnerPhoneE164 func() null.Val[string]
ResidentPhoneE164 func() null.Val[string]
Geom func() null.Val[string]
Tags func() pgtypes.HStore
r fileuploadPoolR
f *Factory
@ -177,10 +179,6 @@ func (o FileuploadPoolTemplate) BuildSetter() *models.FileuploadPoolSetter {
val := o.Deleted()
m.Deleted = omitnull.FromNull(val)
}
if o.Geom != nil {
val := o.Geom()
m.Geom = omitnull.FromNull(val)
}
if o.H3cell != nil {
val := o.H3cell()
m.H3cell = omitnull.FromNull(val)
@ -225,6 +223,14 @@ func (o FileuploadPoolTemplate) BuildSetter() *models.FileuploadPoolSetter {
val := o.ResidentPhoneE164()
m.ResidentPhoneE164 = omitnull.FromNull(val)
}
if o.Geom != nil {
val := o.Geom()
m.Geom = omitnull.FromNull(val)
}
if o.Tags != nil {
val := o.Tags()
m.Tags = omit.From(val)
}
return m
}
@ -274,9 +280,6 @@ func (o FileuploadPoolTemplate) Build() *models.FileuploadPool {
if o.Deleted != nil {
m.Deleted = o.Deleted()
}
if o.Geom != nil {
m.Geom = o.Geom()
}
if o.H3cell != nil {
m.H3cell = o.H3cell()
}
@ -310,6 +313,12 @@ func (o FileuploadPoolTemplate) Build() *models.FileuploadPool {
if o.ResidentPhoneE164 != nil {
m.ResidentPhoneE164 = o.ResidentPhoneE164()
}
if o.Geom != nil {
m.Geom = o.Geom()
}
if o.Tags != nil {
m.Tags = o.Tags()
}
o.setModelRels(m)
@ -386,6 +395,10 @@ func ensureCreatableFileuploadPool(m *models.FileuploadPoolSetter) {
val := random_int32(nil)
m.Version = omit.From(val)
}
if !(m.Tags.IsValue()) {
val := random_pgtypes_HStore(nil)
m.Tags = omit.From(val)
}
}
// insertOptRels creates and inserts any optional the relationships on *models.FileuploadPool
@ -588,7 +601,6 @@ func (m fileuploadPoolMods) RandomizeAllColumns(f *faker.Faker) FileuploadPoolMo
FileuploadPoolMods.RandomCreatorID(f),
FileuploadPoolMods.RandomCSVFile(f),
FileuploadPoolMods.RandomDeleted(f),
FileuploadPoolMods.RandomGeom(f),
FileuploadPoolMods.RandomH3cell(f),
FileuploadPoolMods.RandomID(f),
FileuploadPoolMods.RandomIsInDistrict(f),
@ -600,6 +612,8 @@ func (m fileuploadPoolMods) RandomizeAllColumns(f *faker.Faker) FileuploadPoolMo
FileuploadPoolMods.RandomVersion(f),
FileuploadPoolMods.RandomPropertyOwnerPhoneE164(f),
FileuploadPoolMods.RandomResidentPhoneE164(f),
FileuploadPoolMods.RandomGeom(f),
FileuploadPoolMods.RandomTags(f),
}
}
@ -904,59 +918,6 @@ func (m fileuploadPoolMods) RandomDeletedNotNull(f *faker.Faker) FileuploadPoolM
})
}
// Set the model columns to this value
func (m fileuploadPoolMods) Geom(val null.Val[string]) FileuploadPoolMod {
return FileuploadPoolModFunc(func(_ context.Context, o *FileuploadPoolTemplate) {
o.Geom = func() null.Val[string] { return val }
})
}
// Set the Column from the function
func (m fileuploadPoolMods) GeomFunc(f func() null.Val[string]) FileuploadPoolMod {
return FileuploadPoolModFunc(func(_ context.Context, o *FileuploadPoolTemplate) {
o.Geom = f
})
}
// Clear any values for the column
func (m fileuploadPoolMods) UnsetGeom() FileuploadPoolMod {
return FileuploadPoolModFunc(func(_ context.Context, o *FileuploadPoolTemplate) {
o.Geom = nil
})
}
// Generates a random value for the column using the given faker
// if faker is nil, a default faker is used
// The generated value is sometimes null
func (m fileuploadPoolMods) RandomGeom(f *faker.Faker) FileuploadPoolMod {
return FileuploadPoolModFunc(func(_ context.Context, o *FileuploadPoolTemplate) {
o.Geom = func() null.Val[string] {
if f == nil {
f = &defaultFaker
}
val := random_string(f)
return null.From(val)
}
})
}
// Generates a random value for the column using the given faker
// if faker is nil, a default faker is used
// The generated value is never null
func (m fileuploadPoolMods) RandomGeomNotNull(f *faker.Faker) FileuploadPoolMod {
return FileuploadPoolModFunc(func(_ context.Context, o *FileuploadPoolTemplate) {
o.Geom = func() null.Val[string] {
if f == nil {
f = &defaultFaker
}
val := random_string(f)
return null.From(val)
}
})
}
// Set the model columns to this value
func (m fileuploadPoolMods) H3cell(val null.Val[string]) FileuploadPoolMod {
return FileuploadPoolModFunc(func(_ context.Context, o *FileuploadPoolTemplate) {
@ -1386,6 +1347,90 @@ func (m fileuploadPoolMods) RandomResidentPhoneE164NotNull(f *faker.Faker) Fileu
})
}
// Set the model columns to this value
func (m fileuploadPoolMods) Geom(val null.Val[string]) FileuploadPoolMod {
return FileuploadPoolModFunc(func(_ context.Context, o *FileuploadPoolTemplate) {
o.Geom = func() null.Val[string] { return val }
})
}
// Set the Column from the function
func (m fileuploadPoolMods) GeomFunc(f func() null.Val[string]) FileuploadPoolMod {
return FileuploadPoolModFunc(func(_ context.Context, o *FileuploadPoolTemplate) {
o.Geom = f
})
}
// Clear any values for the column
func (m fileuploadPoolMods) UnsetGeom() FileuploadPoolMod {
return FileuploadPoolModFunc(func(_ context.Context, o *FileuploadPoolTemplate) {
o.Geom = nil
})
}
// Generates a random value for the column using the given faker
// if faker is nil, a default faker is used
// The generated value is sometimes null
func (m fileuploadPoolMods) RandomGeom(f *faker.Faker) FileuploadPoolMod {
return FileuploadPoolModFunc(func(_ context.Context, o *FileuploadPoolTemplate) {
o.Geom = func() null.Val[string] {
if f == nil {
f = &defaultFaker
}
val := random_string(f)
return null.From(val)
}
})
}
// Generates a random value for the column using the given faker
// if faker is nil, a default faker is used
// The generated value is never null
func (m fileuploadPoolMods) RandomGeomNotNull(f *faker.Faker) FileuploadPoolMod {
return FileuploadPoolModFunc(func(_ context.Context, o *FileuploadPoolTemplate) {
o.Geom = func() null.Val[string] {
if f == nil {
f = &defaultFaker
}
val := random_string(f)
return null.From(val)
}
})
}
// Set the model columns to this value
func (m fileuploadPoolMods) Tags(val pgtypes.HStore) FileuploadPoolMod {
return FileuploadPoolModFunc(func(_ context.Context, o *FileuploadPoolTemplate) {
o.Tags = func() pgtypes.HStore { return val }
})
}
// Set the Column from the function
func (m fileuploadPoolMods) TagsFunc(f func() pgtypes.HStore) FileuploadPoolMod {
return FileuploadPoolModFunc(func(_ context.Context, o *FileuploadPoolTemplate) {
o.Tags = f
})
}
// Clear any values for the column
func (m fileuploadPoolMods) UnsetTags() FileuploadPoolMod {
return FileuploadPoolModFunc(func(_ context.Context, o *FileuploadPoolTemplate) {
o.Tags = nil
})
}
// Generates a random value for the column using the given faker
// if faker is nil, a default faker is used
func (m fileuploadPoolMods) RandomTags(f *faker.Faker) FileuploadPoolMod {
return FileuploadPoolModFunc(func(_ context.Context, o *FileuploadPoolTemplate) {
o.Tags = func() pgtypes.HStore {
return random_pgtypes_HStore(f)
}
})
}
func (m fileuploadPoolMods) WithParentsCascading() FileuploadPoolMod {
return FileuploadPoolModFunc(func(ctx context.Context, o *FileuploadPoolTemplate) {
if isDone, _ := fileuploadPoolWithParentsCascadingCtx.Value(ctx); isDone {

View file

@ -0,0 +1,4 @@
-- +goose Up
ALTER TABLE fileupload.pool ADD COLUMN tags HSTORE NOT NULL;
-- +goose Down
ALTER TABLE fileupload.pool DROP COLUMN tags;

View file

@ -36,7 +36,6 @@ type FileuploadPool struct {
CreatorID int32 `db:"creator_id" `
CSVFile int32 `db:"csv_file" `
Deleted null.Val[time.Time] `db:"deleted" `
Geom null.Val[string] `db:"geom" `
H3cell null.Val[string] `db:"h3cell" `
ID int32 `db:"id,pk" `
IsInDistrict bool `db:"is_in_district" `
@ -48,6 +47,8 @@ type FileuploadPool struct {
Version int32 `db:"version,pk" `
PropertyOwnerPhoneE164 null.Val[string] `db:"property_owner_phone_e164" `
ResidentPhoneE164 null.Val[string] `db:"resident_phone_e164" `
Geom null.Val[string] `db:"geom" `
Tags pgtypes.HStore `db:"tags" `
R fileuploadPoolR `db:"-" `
}
@ -74,7 +75,7 @@ type fileuploadPoolR struct {
func buildFileuploadPoolColumns(alias string) fileuploadPoolColumns {
return fileuploadPoolColumns{
ColumnsExpr: expr.NewColumnsExpr(
"address_city", "address_postal_code", "address_street", "committed", "condition", "created", "creator_id", "csv_file", "deleted", "geom", "h3cell", "id", "is_in_district", "is_new", "notes", "organization_id", "property_owner_name", "resident_owned", "version", "property_owner_phone_e164", "resident_phone_e164",
"address_city", "address_postal_code", "address_street", "committed", "condition", "created", "creator_id", "csv_file", "deleted", "h3cell", "id", "is_in_district", "is_new", "notes", "organization_id", "property_owner_name", "resident_owned", "version", "property_owner_phone_e164", "resident_phone_e164", "geom", "tags",
).WithParent("fileupload.pool"),
tableAlias: alias,
AddressCity: psql.Quote(alias, "address_city"),
@ -86,7 +87,6 @@ func buildFileuploadPoolColumns(alias string) fileuploadPoolColumns {
CreatorID: psql.Quote(alias, "creator_id"),
CSVFile: psql.Quote(alias, "csv_file"),
Deleted: psql.Quote(alias, "deleted"),
Geom: psql.Quote(alias, "geom"),
H3cell: psql.Quote(alias, "h3cell"),
ID: psql.Quote(alias, "id"),
IsInDistrict: psql.Quote(alias, "is_in_district"),
@ -98,6 +98,8 @@ func buildFileuploadPoolColumns(alias string) fileuploadPoolColumns {
Version: psql.Quote(alias, "version"),
PropertyOwnerPhoneE164: psql.Quote(alias, "property_owner_phone_e164"),
ResidentPhoneE164: psql.Quote(alias, "resident_phone_e164"),
Geom: psql.Quote(alias, "geom"),
Tags: psql.Quote(alias, "tags"),
}
}
@ -113,7 +115,6 @@ type fileuploadPoolColumns struct {
CreatorID psql.Expression
CSVFile psql.Expression
Deleted psql.Expression
Geom psql.Expression
H3cell psql.Expression
ID psql.Expression
IsInDistrict psql.Expression
@ -125,6 +126,8 @@ type fileuploadPoolColumns struct {
Version psql.Expression
PropertyOwnerPhoneE164 psql.Expression
ResidentPhoneE164 psql.Expression
Geom psql.Expression
Tags psql.Expression
}
func (c fileuploadPoolColumns) Alias() string {
@ -148,7 +151,6 @@ type FileuploadPoolSetter struct {
CreatorID omit.Val[int32] `db:"creator_id" `
CSVFile omit.Val[int32] `db:"csv_file" `
Deleted omitnull.Val[time.Time] `db:"deleted" `
Geom omitnull.Val[string] `db:"geom" `
H3cell omitnull.Val[string] `db:"h3cell" `
ID omit.Val[int32] `db:"id,pk" `
IsInDistrict omit.Val[bool] `db:"is_in_district" `
@ -160,10 +162,12 @@ type FileuploadPoolSetter struct {
Version omit.Val[int32] `db:"version,pk" `
PropertyOwnerPhoneE164 omitnull.Val[string] `db:"property_owner_phone_e164" `
ResidentPhoneE164 omitnull.Val[string] `db:"resident_phone_e164" `
Geom omitnull.Val[string] `db:"geom" `
Tags omit.Val[pgtypes.HStore] `db:"tags" `
}
func (s FileuploadPoolSetter) SetColumns() []string {
vals := make([]string, 0, 21)
vals := make([]string, 0, 22)
if s.AddressCity.IsValue() {
vals = append(vals, "address_city")
}
@ -191,9 +195,6 @@ func (s FileuploadPoolSetter) SetColumns() []string {
if !s.Deleted.IsUnset() {
vals = append(vals, "deleted")
}
if !s.Geom.IsUnset() {
vals = append(vals, "geom")
}
if !s.H3cell.IsUnset() {
vals = append(vals, "h3cell")
}
@ -227,6 +228,12 @@ func (s FileuploadPoolSetter) SetColumns() []string {
if !s.ResidentPhoneE164.IsUnset() {
vals = append(vals, "resident_phone_e164")
}
if !s.Geom.IsUnset() {
vals = append(vals, "geom")
}
if s.Tags.IsValue() {
vals = append(vals, "tags")
}
return vals
}
@ -258,9 +265,6 @@ func (s FileuploadPoolSetter) Overwrite(t *FileuploadPool) {
if !s.Deleted.IsUnset() {
t.Deleted = s.Deleted.MustGetNull()
}
if !s.Geom.IsUnset() {
t.Geom = s.Geom.MustGetNull()
}
if !s.H3cell.IsUnset() {
t.H3cell = s.H3cell.MustGetNull()
}
@ -294,6 +298,12 @@ func (s FileuploadPoolSetter) Overwrite(t *FileuploadPool) {
if !s.ResidentPhoneE164.IsUnset() {
t.ResidentPhoneE164 = s.ResidentPhoneE164.MustGetNull()
}
if !s.Geom.IsUnset() {
t.Geom = s.Geom.MustGetNull()
}
if s.Tags.IsValue() {
t.Tags = s.Tags.MustGet()
}
}
func (s *FileuploadPoolSetter) Apply(q *dialect.InsertQuery) {
@ -302,7 +312,7 @@ func (s *FileuploadPoolSetter) 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, 21)
vals := make([]bob.Expression, 22)
if s.AddressCity.IsValue() {
vals[0] = psql.Arg(s.AddressCity.MustGet())
} else {
@ -357,78 +367,84 @@ func (s *FileuploadPoolSetter) Apply(q *dialect.InsertQuery) {
vals[8] = psql.Raw("DEFAULT")
}
if !s.Geom.IsUnset() {
vals[9] = psql.Arg(s.Geom.MustGetNull())
if !s.H3cell.IsUnset() {
vals[9] = psql.Arg(s.H3cell.MustGetNull())
} else {
vals[9] = psql.Raw("DEFAULT")
}
if !s.H3cell.IsUnset() {
vals[10] = psql.Arg(s.H3cell.MustGetNull())
if s.ID.IsValue() {
vals[10] = psql.Arg(s.ID.MustGet())
} else {
vals[10] = psql.Raw("DEFAULT")
}
if s.ID.IsValue() {
vals[11] = psql.Arg(s.ID.MustGet())
if s.IsInDistrict.IsValue() {
vals[11] = psql.Arg(s.IsInDistrict.MustGet())
} else {
vals[11] = psql.Raw("DEFAULT")
}
if s.IsInDistrict.IsValue() {
vals[12] = psql.Arg(s.IsInDistrict.MustGet())
if s.IsNew.IsValue() {
vals[12] = psql.Arg(s.IsNew.MustGet())
} else {
vals[12] = psql.Raw("DEFAULT")
}
if s.IsNew.IsValue() {
vals[13] = psql.Arg(s.IsNew.MustGet())
if s.Notes.IsValue() {
vals[13] = psql.Arg(s.Notes.MustGet())
} else {
vals[13] = psql.Raw("DEFAULT")
}
if s.Notes.IsValue() {
vals[14] = psql.Arg(s.Notes.MustGet())
if s.OrganizationID.IsValue() {
vals[14] = psql.Arg(s.OrganizationID.MustGet())
} else {
vals[14] = psql.Raw("DEFAULT")
}
if s.OrganizationID.IsValue() {
vals[15] = psql.Arg(s.OrganizationID.MustGet())
if s.PropertyOwnerName.IsValue() {
vals[15] = psql.Arg(s.PropertyOwnerName.MustGet())
} else {
vals[15] = psql.Raw("DEFAULT")
}
if s.PropertyOwnerName.IsValue() {
vals[16] = psql.Arg(s.PropertyOwnerName.MustGet())
if !s.ResidentOwned.IsUnset() {
vals[16] = psql.Arg(s.ResidentOwned.MustGetNull())
} else {
vals[16] = psql.Raw("DEFAULT")
}
if !s.ResidentOwned.IsUnset() {
vals[17] = psql.Arg(s.ResidentOwned.MustGetNull())
if s.Version.IsValue() {
vals[17] = psql.Arg(s.Version.MustGet())
} else {
vals[17] = psql.Raw("DEFAULT")
}
if s.Version.IsValue() {
vals[18] = psql.Arg(s.Version.MustGet())
if !s.PropertyOwnerPhoneE164.IsUnset() {
vals[18] = psql.Arg(s.PropertyOwnerPhoneE164.MustGetNull())
} else {
vals[18] = psql.Raw("DEFAULT")
}
if !s.PropertyOwnerPhoneE164.IsUnset() {
vals[19] = psql.Arg(s.PropertyOwnerPhoneE164.MustGetNull())
if !s.ResidentPhoneE164.IsUnset() {
vals[19] = psql.Arg(s.ResidentPhoneE164.MustGetNull())
} else {
vals[19] = psql.Raw("DEFAULT")
}
if !s.ResidentPhoneE164.IsUnset() {
vals[20] = psql.Arg(s.ResidentPhoneE164.MustGetNull())
if !s.Geom.IsUnset() {
vals[20] = psql.Arg(s.Geom.MustGetNull())
} else {
vals[20] = psql.Raw("DEFAULT")
}
if s.Tags.IsValue() {
vals[21] = psql.Arg(s.Tags.MustGet())
} else {
vals[21] = psql.Raw("DEFAULT")
}
return bob.ExpressSlice(ctx, w, d, start, vals, "", ", ", "")
}))
}
@ -438,7 +454,7 @@ func (s FileuploadPoolSetter) UpdateMod() bob.Mod[*dialect.UpdateQuery] {
}
func (s FileuploadPoolSetter) Expressions(prefix ...string) []bob.Expression {
exprs := make([]bob.Expression, 0, 21)
exprs := make([]bob.Expression, 0, 22)
if s.AddressCity.IsValue() {
exprs = append(exprs, expr.Join{Sep: " = ", Exprs: []bob.Expression{
@ -503,13 +519,6 @@ func (s FileuploadPoolSetter) Expressions(prefix ...string) []bob.Expression {
}})
}
if !s.Geom.IsUnset() {
exprs = append(exprs, expr.Join{Sep: " = ", Exprs: []bob.Expression{
psql.Quote(append(prefix, "geom")...),
psql.Arg(s.Geom),
}})
}
if !s.H3cell.IsUnset() {
exprs = append(exprs, expr.Join{Sep: " = ", Exprs: []bob.Expression{
psql.Quote(append(prefix, "h3cell")...),
@ -587,6 +596,20 @@ func (s FileuploadPoolSetter) Expressions(prefix ...string) []bob.Expression {
}})
}
if !s.Geom.IsUnset() {
exprs = append(exprs, expr.Join{Sep: " = ", Exprs: []bob.Expression{
psql.Quote(append(prefix, "geom")...),
psql.Arg(s.Geom),
}})
}
if s.Tags.IsValue() {
exprs = append(exprs, expr.Join{Sep: " = ", Exprs: []bob.Expression{
psql.Quote(append(prefix, "tags")...),
psql.Arg(s.Tags),
}})
}
return exprs
}
@ -1193,7 +1216,6 @@ type fileuploadPoolWhere[Q psql.Filterable] struct {
CreatorID psql.WhereMod[Q, int32]
CSVFile psql.WhereMod[Q, int32]
Deleted psql.WhereNullMod[Q, time.Time]
Geom psql.WhereNullMod[Q, string]
H3cell psql.WhereNullMod[Q, string]
ID psql.WhereMod[Q, int32]
IsInDistrict psql.WhereMod[Q, bool]
@ -1205,6 +1227,8 @@ type fileuploadPoolWhere[Q psql.Filterable] struct {
Version psql.WhereMod[Q, int32]
PropertyOwnerPhoneE164 psql.WhereNullMod[Q, string]
ResidentPhoneE164 psql.WhereNullMod[Q, string]
Geom psql.WhereNullMod[Q, string]
Tags psql.WhereMod[Q, pgtypes.HStore]
}
func (fileuploadPoolWhere[Q]) AliasedAs(alias string) fileuploadPoolWhere[Q] {
@ -1222,7 +1246,6 @@ func buildFileuploadPoolWhere[Q psql.Filterable](cols fileuploadPoolColumns) fil
CreatorID: psql.Where[Q, int32](cols.CreatorID),
CSVFile: psql.Where[Q, int32](cols.CSVFile),
Deleted: psql.WhereNull[Q, time.Time](cols.Deleted),
Geom: psql.WhereNull[Q, string](cols.Geom),
H3cell: psql.WhereNull[Q, string](cols.H3cell),
ID: psql.Where[Q, int32](cols.ID),
IsInDistrict: psql.Where[Q, bool](cols.IsInDistrict),
@ -1234,6 +1257,8 @@ func buildFileuploadPoolWhere[Q psql.Filterable](cols fileuploadPoolColumns) fil
Version: psql.Where[Q, int32](cols.Version),
PropertyOwnerPhoneE164: psql.WhereNull[Q, string](cols.PropertyOwnerPhoneE164),
ResidentPhoneE164: psql.WhereNull[Q, string](cols.ResidentPhoneE164),
Geom: psql.WhereNull[Q, string](cols.Geom),
Tags: psql.Where[Q, pgtypes.HStore](cols.Tags),
}
}

32
db/pgdata.go Normal file
View file

@ -0,0 +1,32 @@
package db
import (
"database/sql"
"github.com/Gleipnir-Technology/bob/types/pgtypes"
"github.com/rs/zerolog/log"
)
func ConvertFromPGData(d pgtypes.HStore) map[string]string {
result := make(map[string]string, 0)
for k, v := range d {
value, err := v.Value()
if err != nil {
log.Warn().Err(err).Str("key", k).Msg("Failed to convert from HSTORE")
continue
}
value_str, ok := value.(string)
if !ok {
log.Warn().Msg("Failed to convert to string")
}
result[k] = value_str
}
return result
}
func ConvertToPGData(data map[string]string) pgtypes.HStore {
result := pgtypes.HStore{}
for k, v := range data {
result[k] = sql.Null[string]{V: v, Valid: true}
}
return result
}