From 7a361a330d173085693ed9a3724c3f4d7e51273f Mon Sep 17 00:00:00 2001 From: Eli Ribble Date: Thu, 7 May 2026 16:38:42 +0000 Subject: [PATCH] Remove now-extraneous latitude/longitude generated columns Now that we can pull out the geometry directly into a go object we don't need these and they complicate our insertions --- cmd/test-jet/main.go | 2 +- db/dbinfo/address.bob.go | 46 ++---- db/dbinfo/feature.bob.go | 34 +---- db/dbinfo/publicreport.report.bob.go | 22 +-- db/dbinfo/signal.bob.go | 47 +----- .../00150_drop_generated_location_columns.sql | 12 ++ db/models/address.bob.go | 137 ++++++++---------- db/models/feature.bob.go | 76 +++++----- db/models/publicreport.report.bob.go | 12 +- db/models/signal.bob.go | 7 +- db/query/arcgis/account.go | 3 +- db/query/arcgis/oauth.go | 3 +- db/query/arcgis/service_feature.go | 3 +- db/query/arcgis/service_map.go | 3 +- db/query/arcgis/user_privileges.go | 3 +- db/query/public/address.go | 25 +++- db/query/public/compliance_report_request.go | 17 +++ db/query/public/feature.go | 23 +++ db/query/public/feature_pool.go | 27 ++++ db/query/public/job.go | 17 +++ db/query/public/lead.go | 17 +++ db/query/public/signal.go | 4 +- db/query/public/site.go | 4 +- db/query/publicreport/compliance.go | 3 +- db/query/publicreport/image.go | 3 +- db/query/publicreport/nuisance.go | 3 +- db/query/publicreport/report.go | 3 +- db/query/publicreport/report_image.go | 6 +- db/query/publicreport/report_log.go | 3 +- db/query/publicreport/water.go | 3 +- geomutil/geomutil.go | 11 ++ platform/address.go | 54 ++----- platform/background/background.go | 19 ++- platform/compliance.go | 53 ++++--- platform/lead.go | 40 ++--- platform/signal.go | 108 ++++---------- platform/types/address.go | 19 +-- platform/types/location.go | 10 ++ resource/compliance.go | 2 +- resource/lead.go | 6 +- 40 files changed, 426 insertions(+), 464 deletions(-) create mode 100644 db/migrations/00150_drop_generated_location_columns.sql create mode 100644 db/query/public/compliance_report_request.go create mode 100644 db/query/public/feature.go create mode 100644 db/query/public/feature_pool.go create mode 100644 db/query/public/job.go create mode 100644 db/query/public/lead.go diff --git a/cmd/test-jet/main.go b/cmd/test-jet/main.go index 1fc6bcbc..25ca7946 100644 --- a/cmd/test-jet/main.go +++ b/cmd/test-jet/main.go @@ -37,7 +37,7 @@ func main() { os.Exit(4) } //log.Printf("address %d lat %f lng %f", address.ID, *address.LocationLatitude, *address.LocationLongitude) - log.Printf("Address id %d location %s, lat %f, lng %f", address.ID, address.Location, *address.LocationLatitude, *address.LocationLongitude) + log.Printf("Address id %d location %s", address.ID, address.Location) txn.Commit(ctx) /* diff --git a/db/dbinfo/address.bob.go b/db/dbinfo/address.bob.go index 6ad02a97..5c21307d 100644 --- a/db/dbinfo/address.bob.go +++ b/db/dbinfo/address.bob.go @@ -123,24 +123,6 @@ var Addresses = Table[ Generated: false, AutoIncr: false, }, - LocationLatitude: column{ - Name: "location_latitude", - DBType: "double precision", - Default: "GENERATED", - Comment: "", - Nullable: true, - Generated: true, - AutoIncr: false, - }, - LocationLongitude: column{ - Name: "location_longitude", - DBType: "double precision", - Default: "GENERATED", - Comment: "", - Nullable: true, - Generated: true, - AutoIncr: false, - }, }, Indexes: addressIndexes{ AddressPkey: index{ @@ -213,25 +195,23 @@ var Addresses = Table[ } type addressColumns struct { - Country column - Created column - Location column - H3cell column - ID column - Locality column - PostalCode column - Street column - Unit column - Region column - Number column - Gid column - LocationLatitude column - LocationLongitude column + Country column + Created column + Location column + H3cell column + ID column + Locality column + PostalCode column + Street column + Unit column + Region column + Number column + Gid column } func (c addressColumns) AsSlice() []column { return []column{ - c.Country, c.Created, c.Location, c.H3cell, c.ID, c.Locality, c.PostalCode, c.Street, c.Unit, c.Region, c.Number, c.Gid, c.LocationLatitude, c.LocationLongitude, + c.Country, c.Created, c.Location, c.H3cell, c.ID, c.Locality, c.PostalCode, c.Street, c.Unit, c.Region, c.Number, c.Gid, } } diff --git a/db/dbinfo/feature.bob.go b/db/dbinfo/feature.bob.go index 9c61bad8..fb0eb954 100644 --- a/db/dbinfo/feature.bob.go +++ b/db/dbinfo/feature.bob.go @@ -69,24 +69,6 @@ var Features = Table[ Generated: false, AutoIncr: false, }, - LocationLatitude: column{ - Name: "location_latitude", - DBType: "double precision", - Default: "GENERATED", - Comment: "", - Nullable: true, - Generated: true, - AutoIncr: false, - }, - LocationLongitude: column{ - Name: "location_longitude", - DBType: "double precision", - Default: "GENERATED", - Comment: "", - Nullable: true, - Generated: true, - AutoIncr: false, - }, }, Indexes: featureIndexes{ FeaturePkey: index{ @@ -146,19 +128,17 @@ var Features = Table[ } type featureColumns struct { - Created column - CreatorID column - ID column - OrganizationID column - SiteID column - Location column - LocationLatitude column - LocationLongitude column + Created column + CreatorID column + ID column + OrganizationID column + SiteID column + Location column } func (c featureColumns) AsSlice() []column { return []column{ - c.Created, c.CreatorID, c.ID, c.OrganizationID, c.SiteID, c.Location, c.LocationLatitude, c.LocationLongitude, + c.Created, c.CreatorID, c.ID, c.OrganizationID, c.SiteID, c.Location, } } diff --git a/db/dbinfo/publicreport.report.bob.go b/db/dbinfo/publicreport.report.bob.go index c7d7e7e8..4c82df52 100644 --- a/db/dbinfo/publicreport.report.bob.go +++ b/db/dbinfo/publicreport.report.bob.go @@ -186,24 +186,6 @@ var PublicreportReports = Table[ Generated: false, AutoIncr: false, }, - LocationLatitude: column{ - Name: "location_latitude", - DBType: "double precision", - Default: "GENERATED", - Comment: "", - Nullable: true, - Generated: true, - AutoIncr: false, - }, - LocationLongitude: column{ - Name: "location_longitude", - DBType: "double precision", - Default: "GENERATED", - Comment: "", - Nullable: true, - Generated: true, - AutoIncr: false, - }, AddressGid: column{ Name: "address_gid", DBType: "text", @@ -342,8 +324,6 @@ type publicreportReportColumns struct { Reviewed column ReviewerID column Status column - LocationLatitude column - LocationLongitude column AddressGid column ClientUUID column ReporterPhoneCanSMS column @@ -351,7 +331,7 @@ type publicreportReportColumns struct { func (c publicreportReportColumns) AsSlice() []column { return []column{ - c.AddressRaw, c.AddressID, c.Created, c.Location, c.H3cell, c.ID, c.LatlngAccuracyType, c.LatlngAccuracyValue, c.MapZoom, c.OrganizationID, c.PublicID, c.ReporterName, c.ReporterEmail, c.ReporterPhone, c.ReporterContactConsent, c.ReportType, c.Reviewed, c.ReviewerID, c.Status, c.LocationLatitude, c.LocationLongitude, c.AddressGid, c.ClientUUID, c.ReporterPhoneCanSMS, + c.AddressRaw, c.AddressID, c.Created, c.Location, c.H3cell, c.ID, c.LatlngAccuracyType, c.LatlngAccuracyValue, c.MapZoom, c.OrganizationID, c.PublicID, c.ReporterName, c.ReporterEmail, c.ReporterPhone, c.ReporterContactConsent, c.ReportType, c.Reviewed, c.ReviewerID, c.Status, c.AddressGid, c.ClientUUID, c.ReporterPhoneCanSMS, } } diff --git a/db/dbinfo/signal.bob.go b/db/dbinfo/signal.bob.go index f6786ae0..6e7ecfac 100644 --- a/db/dbinfo/signal.bob.go +++ b/db/dbinfo/signal.bob.go @@ -105,15 +105,6 @@ var Signals = Table[ Generated: false, AutoIncr: false, }, - LocationType: column{ - Name: "location_type", - DBType: "text", - Default: "GENERATED", - Comment: "", - Nullable: true, - Generated: true, - AutoIncr: false, - }, FeaturePoolFeatureID: column{ Name: "feature_pool_feature_id", DBType: "integer", @@ -168,23 +159,6 @@ var Signals = Table[ Where: "", Include: []string{}, }, - IdxSignalLocationType: index{ - Type: "btree", - Name: "idx_signal_location_type", - Columns: []indexColumn{ - { - Name: "location_type", - Desc: null.FromCond(false, true), - IsExpression: false, - }, - }, - Unique: false, - Comment: "", - NullsFirst: []bool{false}, - NullsDistinct: false, - Where: "", - Include: []string{}, - }, }, PrimaryKey: &constraint{ Name: "signal_pkey", @@ -257,14 +231,6 @@ var Signals = Table[ }, Expression: "((feature_pool_feature_id IS NULL) OR (report_id IS NULL))", }, - ValidLocationTypes: check{ - constraint: constraint{ - Name: "valid_location_types", - Columns: []string{"location_type"}, - Comment: "", - }, - Expression: "(location_type = ANY (ARRAY['POINT'::text, 'POLYGON'::text, 'MULTIPOLYGON'::text]))", - }, }, Comment: "", } @@ -280,26 +246,24 @@ type signalColumns struct { Type column SiteID column Location column - LocationType column FeaturePoolFeatureID column ReportID column } func (c signalColumns) AsSlice() []column { return []column{ - c.Addressed, c.Addressor, c.Created, c.Creator, c.ID, c.OrganizationID, c.Species, c.Type, c.SiteID, c.Location, c.LocationType, c.FeaturePoolFeatureID, c.ReportID, + c.Addressed, c.Addressor, c.Created, c.Creator, c.ID, c.OrganizationID, c.Species, c.Type, c.SiteID, c.Location, c.FeaturePoolFeatureID, c.ReportID, } } type signalIndexes struct { - SignalPkey index - IdxSignalLocation index - IdxSignalLocationType index + SignalPkey index + IdxSignalLocation index } func (i signalIndexes) AsSlice() []index { return []index{ - i.SignalPkey, i.IdxSignalLocation, i.IdxSignalLocationType, + i.SignalPkey, i.IdxSignalLocation, } } @@ -326,11 +290,10 @@ func (u signalUniques) AsSlice() []constraint { type signalChecks struct { CheckExclusiveReference check - ValidLocationTypes check } func (c signalChecks) AsSlice() []check { return []check{ - c.CheckExclusiveReference, c.ValidLocationTypes, + c.CheckExclusiveReference, } } diff --git a/db/migrations/00150_drop_generated_location_columns.sql b/db/migrations/00150_drop_generated_location_columns.sql new file mode 100644 index 00000000..670780b5 --- /dev/null +++ b/db/migrations/00150_drop_generated_location_columns.sql @@ -0,0 +1,12 @@ +-- +goose Up +ALTER TABLE address + DROP COLUMN location_latitude, + DROP COLUMN location_longitude; +ALTER TABLE feature + DROP COLUMN location_latitude, + DROP COLUMN location_longitude; +ALTER TABLE publicreport.report + DROP COLUMN location_latitude, + DROP COLUMN location_longitude; +ALTER TABLE signal + DROP COLUMN location_type; diff --git a/db/models/address.bob.go b/db/models/address.bob.go index 0e9c072c..2bad012f 100644 --- a/db/models/address.bob.go +++ b/db/models/address.bob.go @@ -18,27 +18,24 @@ import ( "github.com/Gleipnir-Technology/bob/expr" "github.com/Gleipnir-Technology/bob/orm" "github.com/Gleipnir-Technology/bob/types/pgtypes" - "github.com/aarondl/opt/null" "github.com/aarondl/opt/omit" "github.com/aarondl/opt/omitnull" ) // Address is an object representing the database table. type Address struct { - Country string `db:"country" ` - Created time.Time `db:"created" ` - Location string `db:"location" ` - H3cell string `db:"h3cell" ` - ID int32 `db:"id,pk" ` - Locality string `db:"locality" ` - PostalCode string `db:"postal_code" ` - Street string `db:"street" ` - Unit string `db:"unit" ` - Region string `db:"region" ` - Number string `db:"number_" ` - Gid string `db:"gid" ` - LocationLatitude null.Val[float64] `db:"location_latitude,generated" ` - LocationLongitude null.Val[float64] `db:"location_longitude,generated" ` + Country string `db:"country" ` + Created time.Time `db:"created" ` + Location string `db:"location" ` + H3cell string `db:"h3cell" ` + ID int32 `db:"id,pk" ` + Locality string `db:"locality" ` + PostalCode string `db:"postal_code" ` + Street string `db:"street" ` + Unit string `db:"unit" ` + Region string `db:"region" ` + Number string `db:"number_" ` + Gid string `db:"gid" ` R addressR `db:"-" ` } @@ -67,43 +64,39 @@ type addressR struct { func buildAddressColumns(alias string) addressColumns { return addressColumns{ ColumnsExpr: expr.NewColumnsExpr( - "country", "created", "location", "h3cell", "id", "locality", "postal_code", "street", "unit", "region", "number_", "gid", "location_latitude", "location_longitude", + "country", "created", "location", "h3cell", "id", "locality", "postal_code", "street", "unit", "region", "number_", "gid", ).WithParent("address"), - tableAlias: alias, - Country: psql.Quote(alias, "country"), - Created: psql.Quote(alias, "created"), - Location: psql.Quote(alias, "location"), - H3cell: psql.Quote(alias, "h3cell"), - ID: psql.Quote(alias, "id"), - Locality: psql.Quote(alias, "locality"), - PostalCode: psql.Quote(alias, "postal_code"), - Street: psql.Quote(alias, "street"), - Unit: psql.Quote(alias, "unit"), - Region: psql.Quote(alias, "region"), - Number: psql.Quote(alias, "number_"), - Gid: psql.Quote(alias, "gid"), - LocationLatitude: psql.Quote(alias, "location_latitude"), - LocationLongitude: psql.Quote(alias, "location_longitude"), + tableAlias: alias, + Country: psql.Quote(alias, "country"), + Created: psql.Quote(alias, "created"), + Location: psql.Quote(alias, "location"), + H3cell: psql.Quote(alias, "h3cell"), + ID: psql.Quote(alias, "id"), + Locality: psql.Quote(alias, "locality"), + PostalCode: psql.Quote(alias, "postal_code"), + Street: psql.Quote(alias, "street"), + Unit: psql.Quote(alias, "unit"), + Region: psql.Quote(alias, "region"), + Number: psql.Quote(alias, "number_"), + Gid: psql.Quote(alias, "gid"), } } type addressColumns struct { expr.ColumnsExpr - tableAlias string - Country psql.Expression - Created psql.Expression - Location psql.Expression - H3cell psql.Expression - ID psql.Expression - Locality psql.Expression - PostalCode psql.Expression - Street psql.Expression - Unit psql.Expression - Region psql.Expression - Number psql.Expression - Gid psql.Expression - LocationLatitude psql.Expression - LocationLongitude psql.Expression + tableAlias string + Country psql.Expression + Created psql.Expression + Location psql.Expression + H3cell psql.Expression + ID psql.Expression + Locality psql.Expression + PostalCode psql.Expression + Street psql.Expression + Unit psql.Expression + Region psql.Expression + Number psql.Expression + Gid psql.Expression } func (c addressColumns) Alias() string { @@ -1243,20 +1236,18 @@ func (address0 *Address) AttachSite(ctx context.Context, exec bob.Executor, site } type addressWhere[Q psql.Filterable] struct { - Country psql.WhereMod[Q, string] - Created psql.WhereMod[Q, time.Time] - Location psql.WhereMod[Q, string] - H3cell psql.WhereMod[Q, string] - ID psql.WhereMod[Q, int32] - Locality psql.WhereMod[Q, string] - PostalCode psql.WhereMod[Q, string] - Street psql.WhereMod[Q, string] - Unit psql.WhereMod[Q, string] - Region psql.WhereMod[Q, string] - Number psql.WhereMod[Q, string] - Gid psql.WhereMod[Q, string] - LocationLatitude psql.WhereNullMod[Q, float64] - LocationLongitude psql.WhereNullMod[Q, float64] + Country psql.WhereMod[Q, string] + Created psql.WhereMod[Q, time.Time] + Location psql.WhereMod[Q, string] + H3cell psql.WhereMod[Q, string] + ID psql.WhereMod[Q, int32] + Locality psql.WhereMod[Q, string] + PostalCode psql.WhereMod[Q, string] + Street psql.WhereMod[Q, string] + Unit psql.WhereMod[Q, string] + Region psql.WhereMod[Q, string] + Number psql.WhereMod[Q, string] + Gid psql.WhereMod[Q, string] } func (addressWhere[Q]) AliasedAs(alias string) addressWhere[Q] { @@ -1265,20 +1256,18 @@ func (addressWhere[Q]) AliasedAs(alias string) addressWhere[Q] { func buildAddressWhere[Q psql.Filterable](cols addressColumns) addressWhere[Q] { return addressWhere[Q]{ - Country: psql.Where[Q, string](cols.Country), - Created: psql.Where[Q, time.Time](cols.Created), - Location: psql.Where[Q, string](cols.Location), - H3cell: psql.Where[Q, string](cols.H3cell), - ID: psql.Where[Q, int32](cols.ID), - Locality: psql.Where[Q, string](cols.Locality), - PostalCode: psql.Where[Q, string](cols.PostalCode), - Street: psql.Where[Q, string](cols.Street), - Unit: psql.Where[Q, string](cols.Unit), - Region: psql.Where[Q, string](cols.Region), - Number: psql.Where[Q, string](cols.Number), - Gid: psql.Where[Q, string](cols.Gid), - LocationLatitude: psql.WhereNull[Q, float64](cols.LocationLatitude), - LocationLongitude: psql.WhereNull[Q, float64](cols.LocationLongitude), + Country: psql.Where[Q, string](cols.Country), + Created: psql.Where[Q, time.Time](cols.Created), + Location: psql.Where[Q, string](cols.Location), + H3cell: psql.Where[Q, string](cols.H3cell), + ID: psql.Where[Q, int32](cols.ID), + Locality: psql.Where[Q, string](cols.Locality), + PostalCode: psql.Where[Q, string](cols.PostalCode), + Street: psql.Where[Q, string](cols.Street), + Unit: psql.Where[Q, string](cols.Unit), + Region: psql.Where[Q, string](cols.Region), + Number: psql.Where[Q, string](cols.Number), + Gid: psql.Where[Q, string](cols.Gid), } } diff --git a/db/models/feature.bob.go b/db/models/feature.bob.go index 095d6f7d..2b60494a 100644 --- a/db/models/feature.bob.go +++ b/db/models/feature.bob.go @@ -25,14 +25,12 @@ import ( // Feature is an object representing the database table. type Feature struct { - Created time.Time `db:"created" ` - CreatorID int32 `db:"creator_id" ` - ID int32 `db:"id,pk" ` - OrganizationID int32 `db:"organization_id" ` - SiteID int32 `db:"site_id" ` - Location null.Val[string] `db:"location" ` - LocationLatitude null.Val[float64] `db:"location_latitude,generated" ` - LocationLongitude null.Val[float64] `db:"location_longitude,generated" ` + Created time.Time `db:"created" ` + CreatorID int32 `db:"creator_id" ` + ID int32 `db:"id,pk" ` + OrganizationID int32 `db:"organization_id" ` + SiteID int32 `db:"site_id" ` + Location null.Val[string] `db:"location" ` R featureR `db:"-" ` } @@ -58,31 +56,27 @@ type featureR struct { func buildFeatureColumns(alias string) featureColumns { return featureColumns{ ColumnsExpr: expr.NewColumnsExpr( - "created", "creator_id", "id", "organization_id", "site_id", "location", "location_latitude", "location_longitude", + "created", "creator_id", "id", "organization_id", "site_id", "location", ).WithParent("feature"), - tableAlias: alias, - Created: psql.Quote(alias, "created"), - CreatorID: psql.Quote(alias, "creator_id"), - ID: psql.Quote(alias, "id"), - OrganizationID: psql.Quote(alias, "organization_id"), - SiteID: psql.Quote(alias, "site_id"), - Location: psql.Quote(alias, "location"), - LocationLatitude: psql.Quote(alias, "location_latitude"), - LocationLongitude: psql.Quote(alias, "location_longitude"), + tableAlias: alias, + Created: psql.Quote(alias, "created"), + CreatorID: psql.Quote(alias, "creator_id"), + ID: psql.Quote(alias, "id"), + OrganizationID: psql.Quote(alias, "organization_id"), + SiteID: psql.Quote(alias, "site_id"), + Location: psql.Quote(alias, "location"), } } type featureColumns struct { expr.ColumnsExpr - tableAlias string - Created psql.Expression - CreatorID psql.Expression - ID psql.Expression - OrganizationID psql.Expression - SiteID psql.Expression - Location psql.Expression - LocationLatitude psql.Expression - LocationLongitude psql.Expression + tableAlias string + Created psql.Expression + CreatorID psql.Expression + ID psql.Expression + OrganizationID psql.Expression + SiteID psql.Expression + Location psql.Expression } func (c featureColumns) Alias() string { @@ -766,14 +760,12 @@ func (feature0 *Feature) AttachFeaturePool(ctx context.Context, exec bob.Executo } type featureWhere[Q psql.Filterable] struct { - Created psql.WhereMod[Q, time.Time] - CreatorID psql.WhereMod[Q, int32] - ID psql.WhereMod[Q, int32] - OrganizationID psql.WhereMod[Q, int32] - SiteID psql.WhereMod[Q, int32] - Location psql.WhereNullMod[Q, string] - LocationLatitude psql.WhereNullMod[Q, float64] - LocationLongitude psql.WhereNullMod[Q, float64] + Created psql.WhereMod[Q, time.Time] + CreatorID psql.WhereMod[Q, int32] + ID psql.WhereMod[Q, int32] + OrganizationID psql.WhereMod[Q, int32] + SiteID psql.WhereMod[Q, int32] + Location psql.WhereNullMod[Q, string] } func (featureWhere[Q]) AliasedAs(alias string) featureWhere[Q] { @@ -782,14 +774,12 @@ func (featureWhere[Q]) AliasedAs(alias string) featureWhere[Q] { func buildFeatureWhere[Q psql.Filterable](cols featureColumns) featureWhere[Q] { return featureWhere[Q]{ - Created: psql.Where[Q, time.Time](cols.Created), - CreatorID: psql.Where[Q, int32](cols.CreatorID), - ID: psql.Where[Q, int32](cols.ID), - OrganizationID: psql.Where[Q, int32](cols.OrganizationID), - SiteID: psql.Where[Q, int32](cols.SiteID), - Location: psql.WhereNull[Q, string](cols.Location), - LocationLatitude: psql.WhereNull[Q, float64](cols.LocationLatitude), - LocationLongitude: psql.WhereNull[Q, float64](cols.LocationLongitude), + Created: psql.Where[Q, time.Time](cols.Created), + CreatorID: psql.Where[Q, int32](cols.CreatorID), + ID: psql.Where[Q, int32](cols.ID), + OrganizationID: psql.Where[Q, int32](cols.OrganizationID), + SiteID: psql.Where[Q, int32](cols.SiteID), + Location: psql.WhereNull[Q, string](cols.Location), } } diff --git a/db/models/publicreport.report.bob.go b/db/models/publicreport.report.bob.go index f82b6f55..a444d640 100644 --- a/db/models/publicreport.report.bob.go +++ b/db/models/publicreport.report.bob.go @@ -47,8 +47,6 @@ type PublicreportReport struct { Reviewed null.Val[time.Time] `db:"reviewed" ` ReviewerID null.Val[int32] `db:"reviewer_id" ` Status enums.PublicreportReportstatustype `db:"status" ` - LocationLatitude null.Val[float64] `db:"location_latitude,generated" ` - LocationLongitude null.Val[float64] `db:"location_longitude,generated" ` AddressGid string `db:"address_gid" ` ClientUUID null.Val[uuid.UUID] `db:"client_uuid" ` ReporterPhoneCanSMS bool `db:"reporter_phone_can_sms" ` @@ -88,7 +86,7 @@ type publicreportReportR struct { func buildPublicreportReportColumns(alias string) publicreportReportColumns { return publicreportReportColumns{ ColumnsExpr: expr.NewColumnsExpr( - "address_raw", "address_id", "created", "location", "h3cell", "id", "latlng_accuracy_type", "latlng_accuracy_value", "map_zoom", "organization_id", "public_id", "reporter_name", "reporter_email", "reporter_phone", "reporter_contact_consent", "report_type", "reviewed", "reviewer_id", "status", "location_latitude", "location_longitude", "address_gid", "client_uuid", "reporter_phone_can_sms", + "address_raw", "address_id", "created", "location", "h3cell", "id", "latlng_accuracy_type", "latlng_accuracy_value", "map_zoom", "organization_id", "public_id", "reporter_name", "reporter_email", "reporter_phone", "reporter_contact_consent", "report_type", "reviewed", "reviewer_id", "status", "address_gid", "client_uuid", "reporter_phone_can_sms", ).WithParent("publicreport.report"), tableAlias: alias, AddressRaw: psql.Quote(alias, "address_raw"), @@ -110,8 +108,6 @@ func buildPublicreportReportColumns(alias string) publicreportReportColumns { Reviewed: psql.Quote(alias, "reviewed"), ReviewerID: psql.Quote(alias, "reviewer_id"), Status: psql.Quote(alias, "status"), - LocationLatitude: psql.Quote(alias, "location_latitude"), - LocationLongitude: psql.Quote(alias, "location_longitude"), AddressGid: psql.Quote(alias, "address_gid"), ClientUUID: psql.Quote(alias, "client_uuid"), ReporterPhoneCanSMS: psql.Quote(alias, "reporter_phone_can_sms"), @@ -140,8 +136,6 @@ type publicreportReportColumns struct { Reviewed psql.Expression ReviewerID psql.Expression Status psql.Expression - LocationLatitude psql.Expression - LocationLongitude psql.Expression AddressGid psql.Expression ClientUUID psql.Expression ReporterPhoneCanSMS psql.Expression @@ -2133,8 +2127,6 @@ type publicreportReportWhere[Q psql.Filterable] struct { Reviewed psql.WhereNullMod[Q, time.Time] ReviewerID psql.WhereNullMod[Q, int32] Status psql.WhereMod[Q, enums.PublicreportReportstatustype] - LocationLatitude psql.WhereNullMod[Q, float64] - LocationLongitude psql.WhereNullMod[Q, float64] AddressGid psql.WhereMod[Q, string] ClientUUID psql.WhereNullMod[Q, uuid.UUID] ReporterPhoneCanSMS psql.WhereMod[Q, bool] @@ -2165,8 +2157,6 @@ func buildPublicreportReportWhere[Q psql.Filterable](cols publicreportReportColu Reviewed: psql.WhereNull[Q, time.Time](cols.Reviewed), ReviewerID: psql.WhereNull[Q, int32](cols.ReviewerID), Status: psql.Where[Q, enums.PublicreportReportstatustype](cols.Status), - LocationLatitude: psql.WhereNull[Q, float64](cols.LocationLatitude), - LocationLongitude: psql.WhereNull[Q, float64](cols.LocationLongitude), AddressGid: psql.Where[Q, string](cols.AddressGid), ClientUUID: psql.WhereNull[Q, uuid.UUID](cols.ClientUUID), ReporterPhoneCanSMS: psql.Where[Q, bool](cols.ReporterPhoneCanSMS), diff --git a/db/models/signal.bob.go b/db/models/signal.bob.go index 389b274f..c2218d5b 100644 --- a/db/models/signal.bob.go +++ b/db/models/signal.bob.go @@ -36,7 +36,6 @@ type Signal struct { Type enums.Signaltype `db:"type_" ` SiteID null.Val[int32] `db:"site_id" ` Location string `db:"location" ` - LocationType null.Val[string] `db:"location_type,generated" ` FeaturePoolFeatureID null.Val[int32] `db:"feature_pool_feature_id" ` ReportID null.Val[int32] `db:"report_id" ` @@ -66,7 +65,7 @@ type signalR struct { func buildSignalColumns(alias string) signalColumns { return signalColumns{ ColumnsExpr: expr.NewColumnsExpr( - "addressed", "addressor", "created", "creator", "id", "organization_id", "species", "type_", "site_id", "location", "location_type", "feature_pool_feature_id", "report_id", + "addressed", "addressor", "created", "creator", "id", "organization_id", "species", "type_", "site_id", "location", "feature_pool_feature_id", "report_id", ).WithParent("signal"), tableAlias: alias, Addressed: psql.Quote(alias, "addressed"), @@ -79,7 +78,6 @@ func buildSignalColumns(alias string) signalColumns { Type: psql.Quote(alias, "type_"), SiteID: psql.Quote(alias, "site_id"), Location: psql.Quote(alias, "location"), - LocationType: psql.Quote(alias, "location_type"), FeaturePoolFeatureID: psql.Quote(alias, "feature_pool_feature_id"), ReportID: psql.Quote(alias, "report_id"), } @@ -98,7 +96,6 @@ type signalColumns struct { Type psql.Expression SiteID psql.Expression Location psql.Expression - LocationType psql.Expression FeaturePoolFeatureID psql.Expression ReportID psql.Expression } @@ -1052,7 +1049,6 @@ type signalWhere[Q psql.Filterable] struct { Type psql.WhereMod[Q, enums.Signaltype] SiteID psql.WhereNullMod[Q, int32] Location psql.WhereMod[Q, string] - LocationType psql.WhereNullMod[Q, string] FeaturePoolFeatureID psql.WhereNullMod[Q, int32] ReportID psql.WhereNullMod[Q, int32] } @@ -1073,7 +1069,6 @@ func buildSignalWhere[Q psql.Filterable](cols signalColumns) signalWhere[Q] { Type: psql.Where[Q, enums.Signaltype](cols.Type), SiteID: psql.WhereNull[Q, int32](cols.SiteID), Location: psql.Where[Q, string](cols.Location), - LocationType: psql.WhereNull[Q, string](cols.LocationType), FeaturePoolFeatureID: psql.WhereNull[Q, int32](cols.FeaturePoolFeatureID), ReportID: psql.WhereNull[Q, int32](cols.ReportID), } diff --git a/db/query/arcgis/account.go b/db/query/arcgis/account.go index 6f1b9b49..8309ad10 100644 --- a/db/query/arcgis/account.go +++ b/db/query/arcgis/account.go @@ -19,6 +19,7 @@ func AccountFromID(ctx context.Context, org_id string) (model.Account, error) { } func AccountInsert(ctx context.Context, txn bob.Tx, m *model.Account) (model.Account, error) { statement := table.Account.INSERT(table.Account.AllColumns). - MODEL(m) + MODEL(m). + RETURNING(table.Account.AllColumns) return db.ExecuteOneTxBob[model.Account](ctx, txn, statement) } diff --git a/db/query/arcgis/oauth.go b/db/query/arcgis/oauth.go index cb65b9eb..cb1f3ce4 100644 --- a/db/query/arcgis/oauth.go +++ b/db/query/arcgis/oauth.go @@ -12,7 +12,8 @@ import ( func OAuthTokenInsert(ctx context.Context, m *model.OAuthToken) (model.OAuthToken, error) { statement := table.OAuthToken.INSERT(table.OAuthToken.MutableColumns). - MODEL(m) + MODEL(m). + RETURNING(table.OAuthToken.AllColumns) return db.ExecuteOne[model.OAuthToken](ctx, statement) } func OAuthTokenInvalidate(ctx context.Context, id int64) error { diff --git a/db/query/arcgis/service_feature.go b/db/query/arcgis/service_feature.go index bb4950ab..d3b5d094 100644 --- a/db/query/arcgis/service_feature.go +++ b/db/query/arcgis/service_feature.go @@ -26,6 +26,7 @@ func ServiceFeatureFromURL(ctx context.Context, url string) (model.ServiceFeatur } func ServiceFeatureInsert(ctx context.Context, txn bob.Tx, m model.ServiceFeature) error { statement := table.ServiceMap.INSERT(table.ServiceMap.MutableColumns). - MODEL(m) + MODEL(m). + RETURNING(table.ServiceFeature.AllColumns) return db.ExecuteNoneTxBob(ctx, txn, statement) } diff --git a/db/query/arcgis/service_map.go b/db/query/arcgis/service_map.go index 29c8701f..586af32d 100644 --- a/db/query/arcgis/service_map.go +++ b/db/query/arcgis/service_map.go @@ -26,6 +26,7 @@ func ServiceMapsFromAccountID(ctx context.Context, account_id string) ([]model.S } func ServiceMapInsert(ctx context.Context, txn bob.Tx, m *model.ServiceMap) error { statement := table.ServiceMap.INSERT(table.ServiceMap.MutableColumns). - MODEL(m) + MODEL(m). + RETURNING(table.ServiceMap.AllColumns) return db.ExecuteNoneTxBob(ctx, txn, statement) } diff --git a/db/query/arcgis/user_privileges.go b/db/query/arcgis/user_privileges.go index fbac1ece..d3da5005 100644 --- a/db/query/arcgis/user_privileges.go +++ b/db/query/arcgis/user_privileges.go @@ -17,6 +17,7 @@ func UserPrivilegesDeleteByUserID(ctx context.Context, txn bob.Tx, id string) er } func UserPrivilegeInsert(ctx context.Context, txn bob.Tx, m *model.UserPrivilege) error { statement := table.UserPrivilege.INSERT(table.UserPrivilege.MutableColumns). - MODEL(m) + MODEL(m). + RETURNING(table.UserPrivilege.AllColumns) return db.ExecuteNoneTxBob(ctx, txn, statement) } diff --git a/db/query/public/address.go b/db/query/public/address.go index 25952b52..466672a3 100644 --- a/db/query/public/address.go +++ b/db/query/public/address.go @@ -13,6 +13,23 @@ import ( "github.com/go-jet/jet/v2/postgres" ) +func AddressFromComplianceReportRequestID(ctx context.Context, txn db.Ex, public_id string) (model.Address, error) { + statement := table.Address.SELECT( + table.Address.AllColumns, + ).FROM( + table.Address, + table.Site.INNER_JOIN( + table.Site, + table.Site.AddressID.EQ(table.Address.ID)), + table.Site.INNER_JOIN( + table.Lead, + table.Lead.SiteID.EQ(table.Site.ID)), + table.Lead.INNER_JOIN( + table.ComplianceReportRequest, + table.ComplianceReportRequest.LeadID.EQ(table.Lead.ID))). + WHERE(table.ComplianceReportRequest.PublicID.EQ(postgres.String(public_id))) + return db.ExecuteOne[model.Address](ctx, statement) +} func AddressFromGID(ctx context.Context, txn db.Ex, gid string) (*model.Address, error) { statement := table.Address.SELECT( table.Address.AllColumns, @@ -59,11 +76,3 @@ func AddressInserts(ctx context.Context, txn db.Ex, addresses []model.Address) ( RETURNING(table.Address.AllColumns) return db.ExecuteManyTx[model.Address](ctx, txn, statement) } - -func addressQuery() postgres.InsertStatement { - return table.Address.INSERT( - table.Address.MutableColumns, - ) - //im.Into("address", "country", "created", "gid", "h3cell", "id", "locality", "location", "number_", "postal_code", "region", "street", "unit"), - //im.Returning("id"), -} diff --git a/db/query/public/compliance_report_request.go b/db/query/public/compliance_report_request.go new file mode 100644 index 00000000..0c1d6478 --- /dev/null +++ b/db/query/public/compliance_report_request.go @@ -0,0 +1,17 @@ +package public + +import ( + "context" + + "github.com/Gleipnir-Technology/nidus-sync/db" + "github.com/Gleipnir-Technology/nidus-sync/db/gen/nidus-sync/public/model" + "github.com/Gleipnir-Technology/nidus-sync/db/gen/nidus-sync/public/table" + //"github.com/go-jet/jet/v2/postgres" +) + +func ComplianceReportRequestInsert(ctx context.Context, txn db.Ex, m model.ComplianceReportRequest) (model.ComplianceReportRequest, error) { + statement := table.ComplianceReportRequest.INSERT(table.ComplianceReportRequest.MutableColumns). + MODEL(m). + RETURNING(table.ComplianceReportRequest.AllColumns) + return db.ExecuteOne[model.ComplianceReportRequest](ctx, statement) +} diff --git a/db/query/public/feature.go b/db/query/public/feature.go new file mode 100644 index 00000000..e470594b --- /dev/null +++ b/db/query/public/feature.go @@ -0,0 +1,23 @@ +package public + +import ( + "context" + "fmt" + + "github.com/Gleipnir-Technology/nidus-sync/db" + "github.com/Gleipnir-Technology/nidus-sync/db/gen/nidus-sync/public/model" + "github.com/Gleipnir-Technology/nidus-sync/db/gen/nidus-sync/public/table" + "github.com/go-jet/jet/v2/postgres" +) + +func FeaturesFromSiteID(ctx context.Context, txn db.Ex, site_id int64) ([]model.Feature, error) { + statement := table.Feature.SELECT( + table.Feature.AllColumns, + ).FROM(table.Feature). + WHERE(table.Feature.SiteID.EQ(postgres.Int(site_id))) + result, err := db.ExecuteManyTx[model.Feature](ctx, txn, statement) + if err != nil { + return []model.Feature{}, fmt.Errorf("query: %w", err) + } + return result, nil +} diff --git a/db/query/public/feature_pool.go b/db/query/public/feature_pool.go new file mode 100644 index 00000000..2f800bdf --- /dev/null +++ b/db/query/public/feature_pool.go @@ -0,0 +1,27 @@ +package public + +import ( + "context" + "fmt" + + "github.com/Gleipnir-Technology/nidus-sync/db" + "github.com/Gleipnir-Technology/nidus-sync/db/gen/nidus-sync/public/model" + "github.com/Gleipnir-Technology/nidus-sync/db/gen/nidus-sync/public/table" + "github.com/go-jet/jet/v2/postgres" +) + +func FeaturePoolsFromFeatures(ctx context.Context, txn db.Ex, site_ids []int64) ([]model.FeaturePool, error) { + sql_ids := make([]postgres.Expression, len(site_ids)) + for i, site_id := range site_ids { + sql_ids[i] = postgres.Int(site_id) + } + statement := table.FeaturePool.SELECT( + table.FeaturePool.AllColumns, + ).FROM(table.FeaturePool). + WHERE(table.FeaturePool.FeatureID.IN(sql_ids...)) + result, err := db.ExecuteManyTx[model.FeaturePool](ctx, txn, statement) + if err != nil { + return []model.FeaturePool{}, fmt.Errorf("query: %w", err) + } + return result, nil +} diff --git a/db/query/public/job.go b/db/query/public/job.go new file mode 100644 index 00000000..f574b6cf --- /dev/null +++ b/db/query/public/job.go @@ -0,0 +1,17 @@ +package public + +import ( + "context" + + "github.com/Gleipnir-Technology/nidus-sync/db" + "github.com/Gleipnir-Technology/nidus-sync/db/gen/nidus-sync/public/model" + "github.com/Gleipnir-Technology/nidus-sync/db/gen/nidus-sync/public/table" + //"github.com/go-jet/jet/v2/postgres" +) + +func JobInsert(ctx context.Context, txn db.Ex, m model.Job) (model.Job, error) { + statement := table.Job.INSERT(table.Job.MutableColumns). + MODEL(m). + RETURNING(table.Job.AllColumns) + return db.ExecuteOne[model.Job](ctx, statement) +} diff --git a/db/query/public/lead.go b/db/query/public/lead.go new file mode 100644 index 00000000..ce2f4f32 --- /dev/null +++ b/db/query/public/lead.go @@ -0,0 +1,17 @@ +package public + +import ( + "context" + + "github.com/Gleipnir-Technology/nidus-sync/db" + "github.com/Gleipnir-Technology/nidus-sync/db/gen/nidus-sync/public/model" + "github.com/Gleipnir-Technology/nidus-sync/db/gen/nidus-sync/public/table" + //"github.com/go-jet/jet/v2/postgres" +) + +func LeadInsert(ctx context.Context, txn db.Ex, m model.Lead) (model.Lead, error) { + statement := table.Lead.INSERT(table.Lead.MutableColumns). + MODEL(m). + RETURNING(table.Lead.AllColumns) + return db.ExecuteOne[model.Lead](ctx, statement) +} diff --git a/db/query/public/signal.go b/db/query/public/signal.go index 9beaf44b..8c95aa44 100644 --- a/db/query/public/signal.go +++ b/db/query/public/signal.go @@ -3,15 +3,13 @@ package public import ( "context" - //"github.com/Gleipnir-Technology/bob" "github.com/Gleipnir-Technology/nidus-sync/db" - //"github.com/Gleipnir-Technology/nidus-sync/db/gen/nidus-sync/public/enum" "github.com/Gleipnir-Technology/nidus-sync/db/gen/nidus-sync/public/model" "github.com/Gleipnir-Technology/nidus-sync/db/gen/nidus-sync/public/table" //"github.com/go-jet/jet/v2/postgres" ) -func SignalInsert(ctx context.Context, txn db.Tx, m model.Signal) (model.Signal, error) { +func SignalInsert(ctx context.Context, txn db.Ex, m model.Signal) (model.Signal, error) { statement := table.Signal.INSERT(table.Signal.MutableColumns). MODEL(m). RETURNING(table.Signal.AllColumns) diff --git a/db/query/public/site.go b/db/query/public/site.go index 5959b8d0..de634884 100644 --- a/db/query/public/site.go +++ b/db/query/public/site.go @@ -28,11 +28,11 @@ func SiteFromAddressIDForOrg(ctx context.Context, txn db.Ex, address_id int64, o } return &result, nil } -func SiteFromIDForOrg(ctx context.Context, comm_id int64, org_id int64) (model.Site, error) { +func SiteFromIDForOrg(ctx context.Context, txn db.Ex, comm_id int64, org_id int64) (model.Site, error) { statement := table.Site.SELECT( table.Site.AllColumns, ).FROM(table.Site). WHERE(table.Site.ID.EQ(postgres.Int(comm_id)).AND( table.Site.OrganizationID.EQ(postgres.Int(org_id)))) - return db.ExecuteOne[model.Site](ctx, statement) + return db.ExecuteOneTx[model.Site](ctx, txn, statement) } diff --git a/db/query/publicreport/compliance.go b/db/query/publicreport/compliance.go index 92f958f6..c5d2b555 100644 --- a/db/query/publicreport/compliance.go +++ b/db/query/publicreport/compliance.go @@ -29,6 +29,7 @@ func ComplianceFromID(ctx context.Context, txn db.Tx, report_id int64) (model.Co } func ComplianceInsert(ctx context.Context, txn db.Ex, m model.Compliance) (model.Compliance, error) { statement := table.Compliance.INSERT(table.Compliance.AllColumns). - MODEL(m) + MODEL(m). + RETURNING(table.Compliance.AllColumns) return db.ExecuteOneTx[model.Compliance](ctx, txn, statement) } diff --git a/db/query/publicreport/image.go b/db/query/publicreport/image.go index b879ecb4..dac566f1 100644 --- a/db/query/publicreport/image.go +++ b/db/query/publicreport/image.go @@ -11,6 +11,7 @@ import ( func ImageInsert(ctx context.Context, txn db.Ex, m model.Image) (model.Image, error) { statement := table.Image.INSERT(table.Image.AllColumns). - MODEL(m) + MODEL(m). + RETURNING(table.Image.AllColumns) return db.ExecuteOneTx[model.Image](ctx, txn, statement) } diff --git a/db/query/publicreport/nuisance.go b/db/query/publicreport/nuisance.go index eefe7f5b..34cda6cc 100644 --- a/db/query/publicreport/nuisance.go +++ b/db/query/publicreport/nuisance.go @@ -12,6 +12,7 @@ import ( func NuisanceInsert(ctx context.Context, txn db.Ex, m model.Nuisance) (model.Nuisance, error) { statement := table.Nuisance.INSERT(table.Nuisance.AllColumns). - MODEL(m) + MODEL(m). + RETURNING(table.Nuisance.AllColumns) return db.ExecuteOneTx[model.Nuisance](ctx, txn, statement) } diff --git a/db/query/publicreport/report.go b/db/query/publicreport/report.go index 5e8ed429..9a323da3 100644 --- a/db/query/publicreport/report.go +++ b/db/query/publicreport/report.go @@ -17,7 +17,8 @@ type ReportUpdater = db.Updater[table.ReportTable, model.Report] func ReportInsert(ctx context.Context, txn db.Ex, m model.Report) (model.Report, error) { statement := table.Report.INSERT(table.Report.AllColumns). - MODEL(m) + MODEL(m). + RETURNING(table.Report.AllColumns) return db.ExecuteOneTx[model.Report](ctx, txn, statement) } func ReportFromID(ctx context.Context, report_id int64) (model.Report, error) { diff --git a/db/query/publicreport/report_image.go b/db/query/publicreport/report_image.go index 1560e9c0..523e0a03 100644 --- a/db/query/publicreport/report_image.go +++ b/db/query/publicreport/report_image.go @@ -11,11 +11,13 @@ import ( func ReportImageInsert(ctx context.Context, txn db.Ex, m model.ReportImage) (model.ReportImage, error) { statement := table.ReportImage.INSERT(table.ReportImage.AllColumns). - MODEL(m) + MODEL(m). + RETURNING(table.ReportImage.AllColumns) return db.ExecuteOneTx[model.ReportImage](ctx, txn, statement) } func ReportImagesInsert(ctx context.Context, txn db.Ex, m []model.ReportImage) ([]model.ReportImage, error) { statement := table.ReportImage.INSERT(table.ReportImage.AllColumns). - MODELS(m) + MODELS(m). + RETURNING(table.ReportImage.AllColumns) return db.ExecuteManyTx[model.ReportImage](ctx, txn, statement) } diff --git a/db/query/publicreport/report_log.go b/db/query/publicreport/report_log.go index a7e099f2..c64fa3fc 100644 --- a/db/query/publicreport/report_log.go +++ b/db/query/publicreport/report_log.go @@ -11,6 +11,7 @@ import ( func ReportLogInsert(ctx context.Context, txn db.Ex, m model.ReportLog) (model.ReportLog, error) { statement := table.ReportLog.INSERT(table.ReportLog.AllColumns). - MODEL(m) + MODEL(m). + RETURNING(table.ReportLog.AllColumns) return db.ExecuteOneTx[model.ReportLog](ctx, txn, statement) } diff --git a/db/query/publicreport/water.go b/db/query/publicreport/water.go index eb4d9c77..e7b83a5d 100644 --- a/db/query/publicreport/water.go +++ b/db/query/publicreport/water.go @@ -12,6 +12,7 @@ import ( func WaterInsert(ctx context.Context, txn db.Ex, m model.Water) (model.Water, error) { statement := table.Water.INSERT(table.Water.AllColumns). - MODEL(m) + MODEL(m). + RETURNING(table.Water.AllColumns) return db.ExecuteOneTx[model.Water](ctx, txn, statement) } diff --git a/geomutil/geomutil.go b/geomutil/geomutil.go index 1d8767c0..f16aba47 100644 --- a/geomutil/geomutil.go +++ b/geomutil/geomutil.go @@ -1,9 +1,20 @@ package geomutil import ( + "errors" "github.com/twpayne/go-geom" ) +func AsPoint(g geom.T) (geom.Point, error) { + p, ok := g.(*geom.Point) + if !ok { + return geom.Point{}, errors.New("not a point") + } + if p == nil { + return geom.Point{}, errors.New("nil point") + } + return *p, nil +} func PointFromLngLat(lng, lat float64) geom.T { return geom.NewPointFlat(geom.XY, []float64{lng, lat}) } diff --git a/platform/address.go b/platform/address.go index 07d0590a..51dea77b 100644 --- a/platform/address.go +++ b/platform/address.go @@ -2,63 +2,39 @@ package platform import ( "context" + "errors" "fmt" - "github.com/Gleipnir-Technology/bob" - "github.com/Gleipnir-Technology/bob/dialect/psql" - "github.com/Gleipnir-Technology/bob/dialect/psql/sm" "github.com/Gleipnir-Technology/nidus-sync/db" - "github.com/Gleipnir-Technology/nidus-sync/db/models" + querypublic "github.com/Gleipnir-Technology/nidus-sync/db/query/public" "github.com/Gleipnir-Technology/nidus-sync/platform/types" - "github.com/stephenafamo/scan" ) type Address = types.Address func AddressFromComplianceReportRequestID(ctx context.Context, public_id string) (*types.Address, error) { - row, err := bob.One(ctx, db.PGInstance.BobDB, psql.Select( - sm.Columns( - models.Addresses.Columns.Country, - models.Addresses.Columns.Gid, - models.Addresses.Columns.ID, - models.Addresses.Columns.Locality, - models.Addresses.Columns.LocationLatitude.As("location.latitude"), - models.Addresses.Columns.LocationLongitude.As("location.longitude"), - models.Addresses.Columns.Number, - models.Addresses.Columns.PostalCode, - models.Addresses.Columns.Region, - models.Addresses.Columns.Street, - models.Addresses.Columns.Unit, - ), - //sm.From(models.Addresses.NameAs()), - sm.From(models.ComplianceReportRequests.NameAs()), - sm.InnerJoin(models.Leads.NameAs()).On( - models.ComplianceReportRequests.Columns.LeadID.EQ(models.Leads.Columns.ID)), - sm.InnerJoin(models.Sites.NameAs()).On( - models.Leads.Columns.SiteID.EQ(models.Sites.Columns.ID)), - sm.InnerJoin(models.Addresses.NameAs()).On( - models.Sites.Columns.AddressID.EQ(models.Addresses.Columns.ID)), - sm.Where(models.ComplianceReportRequests.Columns.PublicID.EQ(psql.Arg(public_id))), - ), scan.StructMapper[*types.Address]()) + row, err := querypublic.AddressFromComplianceReportRequestID(ctx, db.PGInstance.PGXPool, public_id) if err != nil { + if errors.Is(err, db.ErrNoRows) { + return nil, nil + } return nil, fmt.Errorf("query address from compliance report request: %w", err) } - return row, nil + result := types.AddressFromModel(row) + return &result, nil } func AddressLocation(ctx context.Context, address types.Address) (*types.Location, error) { - row, err := bob.One(ctx, db.PGInstance.BobDB, psql.Select( - sm.Columns( - models.Addresses.Columns.LocationLatitude.As("latitude"), - models.Addresses.Columns.LocationLongitude.As("longitude"), - ), - sm.From(models.Addresses.NameAs()), - sm.Where(models.Addresses.Columns.ID.EQ(psql.Arg(address.ID))), - ), scan.StructMapper[*types.Location]()) + address_id := int64(*address.ID) + addr, err := querypublic.AddressFromID(ctx, db.PGInstance.PGXPool, address_id) if err != nil { return nil, fmt.Errorf("query address: %w", err) } - return row, nil + l, err := types.LocationFromGeom(addr.Location) + if err != nil { + return nil, fmt.Errorf("location from geom: %w", err) + } + return &l, nil } func AddressInsert(ctx context.Context) (*types.Address, error) { diff --git a/platform/background/background.go b/platform/background/background.go index 2dfbab29..d43cd3a6 100644 --- a/platform/background/background.go +++ b/platform/background/background.go @@ -6,8 +6,11 @@ import ( "time" "github.com/Gleipnir-Technology/bob" + "github.com/Gleipnir-Technology/nidus-sync/db" "github.com/Gleipnir-Technology/nidus-sync/db/enums" + "github.com/Gleipnir-Technology/nidus-sync/db/gen/nidus-sync/public/model" "github.com/Gleipnir-Technology/nidus-sync/db/models" + query "github.com/Gleipnir-Technology/nidus-sync/db/query/public" "github.com/aarondl/opt/omit" //"github.com/rs/zerolog/log" ) @@ -15,8 +18,8 @@ import ( func NewAudioTranscode(ctx context.Context, txn bob.Executor, audio_id int32) error { return newJob(ctx, txn, enums.JobtypeAudioTranscode, audio_id) } -func NewComplianceMailer(ctx context.Context, txn bob.Executor, compliance_report_request_id int32) error { - return newJob(ctx, txn, enums.JobtypeComplianceMailerSend, compliance_report_request_id) +func NewComplianceMailer(ctx context.Context, txn db.Ex, compliance_report_request_id int32) error { + return newJob2(ctx, txn, model.Jobtype_ComplianceMailerSend, compliance_report_request_id) } func NewCSVCommit(ctx context.Context, txn bob.Executor, csv_id int32) error { return newJob(ctx, txn, enums.JobtypeCSVCommit, csv_id) @@ -48,3 +51,15 @@ func newJob(ctx context.Context, txn bob.Executor, t enums.Jobtype, id int32) er } return nil } +func newJob2(ctx context.Context, txn db.Ex, t model.Jobtype, id int32) error { + job := model.Job{ + Created: time.Now(), + Type: t, + RowID: id, + } + _, err := query.JobInsert(ctx, txn, job) + if err != nil { + return fmt.Errorf("insert job: %w", err) + } + return nil +} diff --git a/platform/compliance.go b/platform/compliance.go index b51ddab5..9f98bd40 100644 --- a/platform/compliance.go +++ b/platform/compliance.go @@ -10,51 +10,45 @@ import ( "github.com/Gleipnir-Technology/bob/dialect/psql" "github.com/Gleipnir-Technology/bob/dialect/psql/sm" "github.com/Gleipnir-Technology/nidus-sync/db" + modelpublic "github.com/Gleipnir-Technology/nidus-sync/db/gen/nidus-sync/public/model" "github.com/Gleipnir-Technology/nidus-sync/db/models" + querypublic "github.com/Gleipnir-Technology/nidus-sync/db/query/public" "github.com/Gleipnir-Technology/nidus-sync/platform/background" "github.com/Gleipnir-Technology/nidus-sync/platform/event" "github.com/Gleipnir-Technology/nidus-sync/platform/types" - "github.com/aarondl/opt/omit" - "github.com/aarondl/opt/omitnull" //"github.com/rs/zerolog/log" "github.com/stephenafamo/scan" ) -func ComplianceRequestMailerCreate(ctx context.Context, user User, site_id int32) (int32, error) { - txn, err := db.PGInstance.BobDB.BeginTx(ctx, nil) +func ComplianceRequestMailerCreate(ctx context.Context, user User, site_id int64) (int32, error) { + txn, err := db.BeginTxn(ctx) if err != nil { return 0, fmt.Errorf("start txn: %w", err) } defer txn.Rollback(ctx) - site, err := models.FindSite(ctx, txn, site_id) + site, err := querypublic.SiteFromIDForOrg(ctx, txn, site_id, int64(user.Organization.ID)) if err != nil { return 0, fmt.Errorf("find site: %w", err) } if site.OrganizationID != user.Organization.ID { return 0, fmt.Errorf("permission denied") } - address, err := models.FindAddress(ctx, txn, site.AddressID) + address, err := querypublic.AddressFromID(ctx, txn, int64(site.AddressID)) if err != nil { return 0, fmt.Errorf("find address %d: %w", site.AddressID, err) } if address.PostalCode == "" { return 0, fmt.Errorf("address %d does not have a postal code", address.ID) } - features, err := models.Features.Query( - models.SelectWhere.Features.SiteID.EQ(site.ID), - ).All(ctx, txn) + features, err := querypublic.FeaturesFromSiteID(ctx, txn, int64(site.ID)) if err != nil { return 0, fmt.Errorf("find features: %w", err) } - feature_ids := make([]int32, len(features)) + feature_ids := make([]int64, len(features)) for i, f := range features { - feature_ids[i] = f.ID + feature_ids[i] = int64(f.ID) } - feature_pools, err := models.FeaturePools.Query( - sm.Where( - models.FeaturePools.Columns.FeatureID.EQ(psql.Any(feature_ids)), - ), - ).All(ctx, txn) + feature_pools, err := querypublic.FeaturePoolsFromFeatures(ctx, txn, feature_ids) if err != nil { return 0, fmt.Errorf("find feature pools: %w", err) } @@ -62,24 +56,27 @@ func ComplianceRequestMailerCreate(ctx context.Context, user User, site_id int32 return 0, fmt.Errorf("wrong number of pools: %d", len(feature_pools)) } feature_pool := feature_pools[0] - var feature *models.Feature + var feature *modelpublic.Feature for _, f := range features { if f.ID == feature_pool.FeatureID { - feature = f + feature = &f } } if feature == nil { return 0, fmt.Errorf("match feature %d", feature_pool.FeatureID) } - location := types.Location{ - Latitude: feature.LocationLatitude.GetOr(0), - Longitude: feature.LocationLongitude.GetOr(0), + if feature.Location == nil { + return 0, fmt.Errorf("nil location %d", feature.ID) + } + location, err := types.LocationFromGeom(*feature.Location) + if err != nil { + return 0, fmt.Errorf("location from geom: %w", err) } signal, err := SignalCreateFromPool(ctx, txn, user, site.ID, feature_pool.FeatureID, location) if err != nil { return 0, fmt.Errorf("create signal from ppol: %w", err) } - lead_id, err := leadCreate(ctx, txn, user, *signal, site.ID, &location) + lead, err := leadCreate(ctx, txn, user, signal.ID, site.ID, &location) if err != nil { return 0, fmt.Errorf("create lead from ppol: %w", err) } @@ -87,14 +84,14 @@ func ComplianceRequestMailerCreate(ctx context.Context, user User, site_id int32 if err != nil { return 0, fmt.Errorf("create public id: %w", err) } - setter := models.ComplianceReportRequestSetter{ - Created: omit.From(time.Now()), - Creator: omit.From(int32(user.ID)), + setter := modelpublic.ComplianceReportRequest{ + Created: time.Now(), + Creator: int32(user.ID), // ID - PublicID: omit.From(public_id), - LeadID: omitnull.From(*lead_id), + PublicID: public_id, + LeadID: &lead.ID, } - req, err := models.ComplianceReportRequests.Insert(&setter).One(ctx, txn) + req, err := querypublic.ComplianceReportRequestInsert(ctx, txn, setter) if err != nil { return 0, fmt.Errorf("create compliance report request: %w", err) } diff --git a/platform/lead.go b/platform/lead.go index 0a846293..b43b55fb 100644 --- a/platform/lead.go +++ b/platform/lead.go @@ -9,44 +9,44 @@ import ( "github.com/Gleipnir-Technology/bob/dialect/psql" "github.com/Gleipnir-Technology/bob/dialect/psql/sm" "github.com/Gleipnir-Technology/nidus-sync/db" - "github.com/Gleipnir-Technology/nidus-sync/db/enums" + "github.com/Gleipnir-Technology/nidus-sync/db/gen/nidus-sync/public/model" "github.com/Gleipnir-Technology/nidus-sync/db/models" + query "github.com/Gleipnir-Technology/nidus-sync/db/query/public" "github.com/Gleipnir-Technology/nidus-sync/platform/types" - "github.com/aarondl/opt/omit" - "github.com/aarondl/opt/omitnull" //"github.com/rs/zerolog/log" "github.com/stephenafamo/scan" ) // Create a lead from the given signal and site -func LeadCreate(ctx context.Context, user User, signal_id int32, site_id int32, pool_location *types.Location) (*int32, error) { - txn, err := db.PGInstance.BobDB.BeginTx(ctx, nil) +func LeadCreate(ctx context.Context, user User, signal_id int32, site_id int32, pool_location *types.Location) (model.Lead, error) { + txn, err := db.BeginTxn(ctx) if err != nil { - return nil, fmt.Errorf("start transaction: %w", err) + return model.Lead{}, fmt.Errorf("start transaction: %w", err) } defer txn.Rollback(ctx) - lead_id, err := leadCreate(ctx, txn, user, signal_id, site_id, pool_location) + lead, err := leadCreate(ctx, txn, user, signal_id, site_id, pool_location) if err != nil { - return nil, fmt.Errorf("inner leadcreate: %w", err) + return model.Lead{}, fmt.Errorf("inner leadcreate: %w", err) } txn.Commit(ctx) - return lead_id, nil + return lead, nil } -func leadCreate(ctx context.Context, txn bob.Executor, user User, signal_id int32, site_id int32, pool_location *types.Location) (*int32, error) { - lead, err := models.Leads.Insert(&models.LeadSetter{ - Created: omit.From(time.Now()), - Creator: omit.From(int32(user.ID)), +func leadCreate(ctx context.Context, txn db.Ex, user User, signal_id int32, site_id int32, pool_location *types.Location) (model.Lead, error) { + lead := model.Lead{ + Created: time.Now(), + Creator: int32(user.ID), // ID - OrganizationID: omit.From(int32(user.Organization.ID)), - SiteID: omitnull.From(site_id), - Type: omit.From(enums.LeadtypeGreenPool), - }).One(ctx, txn) - if err != nil { - return nil, fmt.Errorf("failed to create lead: %w", err) + OrganizationID: int32(user.Organization.ID), + SiteID: &site_id, + Type: model.Leadtype_GreenPool, } - return &lead.ID, nil + lead, err := query.LeadInsert(ctx, txn, lead) + if err != nil { + return model.Lead{}, fmt.Errorf("failed to create lead: %w", err) + } + return lead, nil } func leadsBySiteID(ctx context.Context, site_ids []int32) (map[int32][]*types.Lead, error) { rows, err := bob.All(ctx, db.PGInstance.BobDB, psql.Select( diff --git a/platform/signal.go b/platform/signal.go index b1899392..0a201c89 100644 --- a/platform/signal.go +++ b/platform/signal.go @@ -9,7 +9,6 @@ import ( "github.com/Gleipnir-Technology/bob" "github.com/Gleipnir-Technology/bob/dialect/psql" - "github.com/Gleipnir-Technology/bob/dialect/psql/im" "github.com/Gleipnir-Technology/bob/dialect/psql/sm" "github.com/Gleipnir-Technology/nidus-sync/db" modelpublic "github.com/Gleipnir-Technology/nidus-sync/db/gen/nidus-sync/public/model" @@ -17,7 +16,6 @@ import ( tablepublicreport "github.com/Gleipnir-Technology/nidus-sync/db/gen/nidus-sync/publicreport/table" querypublic "github.com/Gleipnir-Technology/nidus-sync/db/query/public" querypublicreport "github.com/Gleipnir-Technology/nidus-sync/db/query/publicreport" - "github.com/Gleipnir-Technology/nidus-sync/geomutil" "github.com/Gleipnir-Technology/nidus-sync/platform/event" "github.com/Gleipnir-Technology/nidus-sync/platform/publicreport" "github.com/Gleipnir-Technology/nidus-sync/platform/types" @@ -44,71 +42,28 @@ type _rowWithID struct { ID int32 `db:"id"` } -func SignalCreateFromPool(ctx context.Context, txn bob.Executor, user User, site_id int32, feature_id int32, location types.Location) (*int32, error) { - /* - setter := models.SignalSetter{ - Addressed: omitnull.FromPtr[time.Time](nil), - Addressor: omitnull.FromPtr[int32](nil), - Created: omit.From(time.Now()), - Creator: omit.From(int32(user.ID)), - //ID - OrganizationID: omit.From(user.Organization.ID), - Species: omitnull.FromPtr[enums.Mosquitospecies](nil), - Type: omit.From(enums.SignaltypeFlyoverPool), - SiteID: omitnull.From(site_id), - Location: omit.From(""), - //Location: - //LocationType null.Val[string] `db:"location_type,generated" ` - FeaturePoolFeatureID: omitnull.From(feature_id), - ReportID: omitnull.FromPtr[int32](nil), - } - signal, err := models.Signals.Insert(&setter).One(ctx, db.PGInstance.BobDB) - */ - query := psql.Insert( - im.Into("signal", - "addressed", - "addressor", - "created", - "creator", - "feature_pool_feature_id", - "id", - "location", - "organization_id", - "report_id", - "site_id", - "species", - "type_", - ), - im.Values( - psql.Raw("NULL"), - psql.Raw("NULL"), - psql.Arg(time.Now()), - psql.Arg(user.ID), - psql.Arg(feature_id), - psql.Raw("DEFAULT"), - psql.F("ST_Point", location.Longitude, location.Latitude, 4326), - psql.Arg(user.Organization.ID), - psql.Raw("NULL"), - psql.Arg(site_id), - psql.Raw("NULL"), - psql.Arg("flyover pool"), - ), - im.Returning("id"), - ) - row, err := bob.One(ctx, txn, query, scan.StructMapper[_rowWithID]()) - if err != nil { - return nil, fmt.Errorf("insert signal: %w", err) +func SignalCreateFromPool(ctx context.Context, txn db.Ex, user User, site_id int32, feature_id int32, location types.Location) (modelpublic.Signal, error) { + g := location.ToGeom() + signal := modelpublic.Signal{ + Addressed: nil, + Addressor: nil, + Created: time.Now(), + Creator: int32(user.ID), + FeaturePoolFeatureID: &feature_id, + //ID + Location: g, + OrganizationID: user.Organization.ID, + ReportID: nil, + SiteID: &site_id, + Species: nil, + Type: modelpublic.Signaltype_FlyoverPool, } - /* - geom_query, _ := location.GeometryQuery() - _, err = psql.Update( - um.Table(models.Signals.Name()), - um.SetCol(models.Signals.Columns.Location.String()).To(geom_query), - um.Where(models.Signals.Columns.ID.EQ(psql.Arg(row.ID))), - ).Exec(ctx, txn) - */ - - return &row.ID, nil + var err error + signal, err = querypublic.SignalInsert(ctx, txn, signal) + if err != nil { + return modelpublic.Signal{}, fmt.Errorf("insert signal: %w", err) + } + return signal, nil } // Create a lead from the given signal and site @@ -139,19 +94,18 @@ func SignalCreateFromPublicreport(ctx context.Context, user User, report_id stri return nil, fmt.Errorf("site from address: %w", err) } site_id = site.ID - location = geomutil.PointFromLngLat(*address.LocationLongitude, *address.LocationLatitude) - } else if report.LocationLatitude != nil && report.LocationLongitude != nil { - lat := report.LocationLatitude - lng := report.LocationLongitude - site, err := siteFromLocation(ctx, txn, user, types.Location{ - Latitude: *lat, - Longitude: *lng, - }) + location = address.Location + } else if report.Location != nil { + l, err := types.LocationFromGeom(*report.Location) + if err != nil { + return nil, fmt.Errorf("report location to geom: %w", err) + } + site, err := siteFromLocation(ctx, txn, user, l) if err != nil { return nil, fmt.Errorf("site from address: %w", err) } site_id = site.ID - location = geomutil.PointFromLngLat(*lng, *lat) + location = *report.Location } else if report.AddressRaw != "" { // At this point we don't have an address, and we don't have GPS // We'll try geocoding and creating an address from that. @@ -164,9 +118,7 @@ func SignalCreateFromPublicreport(ctx context.Context, user User, report_id stri return nil, fmt.Errorf("find address from raw: %w", err) } site_id = site.ID - lat := address.LocationLatitude - lng := address.LocationLongitude - location = geomutil.PointFromLngLat(*lng, *lat) + location = address.Location } else { // We have no structured address, no GPS, no unstructued address. // There's really nothing we can make this lead from and have it be meaningful diff --git a/platform/types/address.go b/platform/types/address.go index d6a02ec0..5d24c8e1 100644 --- a/platform/types/address.go +++ b/platform/types/address.go @@ -10,7 +10,7 @@ import ( "github.com/Gleipnir-Technology/nidus-sync/db" "github.com/Gleipnir-Technology/nidus-sync/db/gen/nidus-sync/public/model" - //"github.com/rs/zerolog/log" + "github.com/rs/zerolog/log" "github.com/stephenafamo/scan" ) @@ -33,15 +33,16 @@ func (a Address) String() string { } func AddressFromModel(m model.Address) Address { //log.Debug().Int32("id", m.ID).Float64("lat", m.LocationLatitude.GetOr(0.0)).Float64("lng", m.LocationLongitude.GetOr(0.0)).Msg("converting address") + l, err := LocationFromGeom(m.Location) + if err != nil { + log.Error().Err(err).Int32("id", m.ID).Msg("getting location for address") + } return Address{ - Country: m.Country, - GID: m.Gid, - ID: &m.ID, - Locality: m.Locality, - Location: &Location{ - Latitude: *m.LocationLatitude, - Longitude: *m.LocationLongitude, - }, + Country: m.Country, + GID: m.Gid, + ID: &m.ID, + Locality: m.Locality, + Location: &l, Number: m.Number, PostalCode: m.PostalCode, Raw: addressToRaw(m), diff --git a/platform/types/location.go b/platform/types/location.go index 61f00a8b..00c29f63 100644 --- a/platform/types/location.go +++ b/platform/types/location.go @@ -42,6 +42,16 @@ func (l Location) ToGeom() geom.T { func LocationFromFS(pl *models.FieldseekerPointlocation) Location { return Location{} } +func LocationFromGeom(g geom.T) (Location, error) { + p, err := geomutil.AsPoint(g) + if err != nil { + return Location{}, fmt.Errorf("as point: %w", err) + } + return Location{ + Latitude: p.Y(), + Longitude: p.X(), + }, nil +} func LocationDistance(l1 Location, l2 Location) float64 { lat_delta := l1.Latitude - l2.Latitude lng_delta := l1.Longitude - l2.Longitude diff --git a/resource/compliance.go b/resource/compliance.go index d8be07c9..4c64f883 100644 --- a/resource/compliance.go +++ b/resource/compliance.go @@ -31,7 +31,7 @@ type complianceRequestMailerForm struct { } func (res *complianceRequestR) CreateMailer(ctx context.Context, r *http.Request, user platform.User, n complianceRequestMailerForm) (*complianceRequestMailer, *nhttp.ErrorWithStatus) { - id, err := platform.ComplianceRequestMailerCreate(ctx, user, n.SiteID) + id, err := platform.ComplianceRequestMailerCreate(ctx, user, int64(n.SiteID)) if err != nil { return nil, nhttp.NewError("create mailer: %w", err) } diff --git a/resource/lead.go b/resource/lead.go index 139c36d0..9bd68c65 100644 --- a/resource/lead.go +++ b/resource/lead.go @@ -54,10 +54,10 @@ func (res *leadR) Create(ctx context.Context, r *http.Request, user platform.Use if err != nil || site_id == nil { return "", nhttp.NewError("site from signal: %w", err) } - lead_id, err := platform.LeadCreate(ctx, user, int32(signal_id), *site_id, pool_location) - if err != nil || lead_id == nil { + lead, err := platform.LeadCreate(ctx, user, int32(signal_id), *site_id, pool_location) + if err != nil { return "", nhttp.NewError("lead create: %w", err) } - return fmt.Sprintf("/lead/%d", *lead_id), nil + return fmt.Sprintf("/lead/%d", lead.ID), nil }