diff --git a/db/query/public/feature.go b/db/query/public/feature.go index e470594b..adc5dbd6 100644 --- a/db/query/public/feature.go +++ b/db/query/public/feature.go @@ -21,3 +21,18 @@ func FeaturesFromSiteID(ctx context.Context, txn db.Ex, site_id int64) ([]model. } return result, nil } +func FeaturesFromSiteIDs(ctx context.Context, txn db.Ex, site_ids []int64) ([]model.Feature, 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.Feature.SELECT( + table.Feature.AllColumns, + ).FROM(table.Feature). + WHERE(table.Feature.SiteID.IN(sql_ids...)) + 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 index 2f800bdf..abc7dd98 100644 --- a/db/query/public/feature_pool.go +++ b/db/query/public/feature_pool.go @@ -10,9 +10,9 @@ import ( "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 { +func FeaturePoolsFromFeatures(ctx context.Context, txn db.Ex, feature_ids []int64) ([]model.FeaturePool, error) { + sql_ids := make([]postgres.Expression, len(feature_ids)) + for i, site_id := range feature_ids { sql_ids[i] = postgres.Int(site_id) } statement := table.FeaturePool.SELECT( diff --git a/platform/feature.go b/platform/feature.go index 6e6f10e6..04d8b4ed 100644 --- a/platform/feature.go +++ b/platform/feature.go @@ -6,54 +6,69 @@ import ( //"github.com/aarondl/opt/omit" //"github.com/aarondl/opt/omitnull" - "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" + modelpublic "github.com/Gleipnir-Technology/nidus-sync/db/gen/nidus-sync/public/model" + querypublic "github.com/Gleipnir-Technology/nidus-sync/db/query/public" "github.com/Gleipnir-Technology/nidus-sync/platform/types" - "github.com/stephenafamo/scan" + "github.com/rs/zerolog/log" ) -func FeaturesForSite(ctx context.Context, site_id int32) ([]types.Feature, error) { - features, err := featuresBySiteID(ctx, []int32{site_id}) +func FeaturesForSite(ctx context.Context, site_id int64) ([]types.Feature, error) { + features, err := featuresBySiteID(ctx, []int64{site_id}) if err != nil { return nil, fmt.Errorf("features by site ID: %w", err) } - return features[site_id], nil + return features[int32(site_id)], nil } -func featuresBySiteID(ctx context.Context, site_ids []int32) (map[int32][]types.Feature, error) { - rows, err := bob.All(ctx, db.PGInstance.BobDB, psql.Select( - sm.Columns( - "feature.id AS id", - "feature.site_id AS site_id", - "COALESCE(feature.location_longitude, 0) AS \"location.longitude\"", - "COALESCE(feature.location_latitude, 0) AS \"location.latitude\"", - "'pool' AS type", - ), - sm.From("feature"), - sm.InnerJoin("feature_pool").OnEQ( - psql.Quote("feature", "id"), - psql.Quote("feature_pool", "feature_id"), - ), - sm.Where( - models.Features.Columns.SiteID.EQ(psql.Any(site_ids)), - ), - ), scan.StructMapper[types.Feature]()) +func featuresBySiteID(ctx context.Context, site_ids []int64) (map[int32][]types.Feature, error) { + features, err := querypublic.FeaturesFromSiteIDs(ctx, db.PGInstance.PGXPool, site_ids) if err != nil { return nil, fmt.Errorf("query features: %w", err) } + feature_ids := make([]int64, len(features)) + for i, feature := range features { + feature_ids[i] = int64(feature.ID) + } + + feature_pools, err := querypublic.FeaturePoolsFromFeatures(ctx, db.PGInstance.PGXPool, feature_ids) + if err != nil { + return nil, fmt.Errorf("query feature pools: %w", err) + } + feature_pools_by_feature_id := make(map[int32]modelpublic.FeaturePool, len(feature_pools)) + for _, feature_pool := range feature_pools { + feature_pools_by_feature_id[feature_pool.FeatureID] = feature_pool + } + results := make(map[int32][]types.Feature, len(site_ids)) for _, site_id := range site_ids { - results[site_id] = make([]types.Feature, 0) + results[int32(site_id)] = make([]types.Feature, 0) } - for _, row := range rows { + for _, row := range features { features, ok := results[row.SiteID] if !ok { return nil, fmt.Errorf("impossible") } - features = append(features, row) + /* + feature_pools, ok := feature_pools_by_feature_id[row.ID] + if !ok { + return nil, fmt.Errorf("impossible 2") + } + */ + if row.Location == nil { + log.Warn().Int32("id", row.ID).Msg("nil location") + continue + } + location, err := types.LocationFromGeom(*row.Location) + if err != nil { + return nil, fmt.Errorf("location from geom on %d: %w", row.SiteID, err) + } + features = append(features, types.Feature{ + ID: row.ID, + Location: location, + SiteID: row.SiteID, + Type: "pool", + }) results[row.SiteID] = features } return results, nil diff --git a/platform/lead.go b/platform/lead.go index b43b55fb..8ba7453f 100644 --- a/platform/lead.go +++ b/platform/lead.go @@ -48,7 +48,7 @@ func leadCreate(ctx context.Context, txn db.Ex, user User, signal_id int32, site } return lead, nil } -func leadsBySiteID(ctx context.Context, site_ids []int32) (map[int32][]*types.Lead, error) { +func leadsBySiteID(ctx context.Context, site_ids []int64) (map[int32][]*types.Lead, error) { rows, err := bob.All(ctx, db.PGInstance.BobDB, psql.Select( sm.Columns( models.Leads.Columns.ID.As("id"), @@ -77,7 +77,7 @@ func leadsBySiteID(ctx context.Context, site_ids []int32) (map[int32][]*types.Le } results := make(map[int32][]*types.Lead, len(site_ids)) for _, site_id := range site_ids { - results[site_id] = make([]*types.Lead, 0) + results[int32(site_id)] = make([]*types.Lead, 0) } for _, row := range rows { leads, ok := results[row.SiteID] diff --git a/platform/site.go b/platform/site.go index cb567a61..7e215a7f 100644 --- a/platform/site.go +++ b/platform/site.go @@ -165,11 +165,11 @@ func siteQueryToRows(ctx context.Context, query bob.BaseQuery[*dialect.SelectQue if err != nil { return nil, fmt.Errorf("query sites: %w", err) } - site_ids := make([]int32, len(rows)) + site_ids := make([]int64, len(rows)) results := make([]*types.Site, len(rows)) for i, row := range rows { results[i] = &row - site_ids[i] = row.ID + site_ids[i] = int64(row.ID) } features_by_site_id, err := featuresBySiteID(ctx, site_ids) if err != nil { diff --git a/resource/compliance.go b/resource/compliance.go index 4c64f883..cbfd0318 100644 --- a/resource/compliance.go +++ b/resource/compliance.go @@ -86,7 +86,7 @@ func imagePoolGet(ctx context.Context, w http.ResponseWriter, public_id string) if err != nil { return fmt.Errorf("find address: %w", err) } - features, err := platform.FeaturesForSite(ctx, site.ID) + features, err := platform.FeaturesForSite(ctx, int64(site.ID)) if err != nil { return fmt.Errorf("get features: %w", err) }