Remove string-based queries for public report data
Use the new jet hotness
This commit is contained in:
parent
12213fb31b
commit
61ad3fbe45
4 changed files with 115 additions and 86 deletions
|
|
@ -39,6 +39,18 @@ func ReportsFromIDs(ctx context.Context, report_ids []int64) ([]model.Report, er
|
|||
WHERE(table.Report.ID.IN(sql_ids...))
|
||||
return db.ExecuteMany[model.Report](ctx, statement)
|
||||
}
|
||||
func ReportsFromIDsForOrg(ctx context.Context, txn db.Ex, report_ids []int64, org_id int64) ([]model.Report, error) {
|
||||
sql_ids := make([]postgres.Expression, len(report_ids))
|
||||
for i, report_id := range report_ids {
|
||||
sql_ids[i] = postgres.Int(report_id)
|
||||
}
|
||||
statement := table.Report.SELECT(
|
||||
table.Report.AllColumns,
|
||||
).FROM(table.Report).
|
||||
WHERE(table.Report.ID.IN(sql_ids...).AND(
|
||||
table.Report.OrganizationID.EQ(postgres.Int(org_id))))
|
||||
return db.ExecuteManyTx[model.Report](ctx, txn, statement)
|
||||
}
|
||||
func ReportFromPublicID(ctx context.Context, txn db.Ex, public_id string) (*model.Report, error) {
|
||||
statement := table.Report.SELECT(
|
||||
table.Report.AllColumns,
|
||||
|
|
@ -68,3 +80,11 @@ func ReportFromPublicIDForOrg(ctx context.Context, txn db.Ex, public_id string,
|
|||
}
|
||||
return &result, nil
|
||||
}
|
||||
func ReportsUnreviewedForOrganization(ctx context.Context, txn db.Ex, org_id int64) ([]model.Report, error) {
|
||||
statement := table.Report.SELECT(
|
||||
table.Report.AllColumns,
|
||||
).FROM(table.Report).
|
||||
WHERE(table.Report.Reviewed.IS_NULL().AND(
|
||||
table.Report.OrganizationID.EQ(postgres.Int(org_id))))
|
||||
return db.ExecuteManyTx[model.Report](ctx, txn, statement)
|
||||
}
|
||||
|
|
|
|||
|
|
@ -213,8 +213,8 @@ func PublicReportUpdateCompliance(ctx context.Context, public_id string, report_
|
|||
func PublicReportReporterUpdated(ctx context.Context, org_id int32, report_id string) {
|
||||
event.Updated(event.TypeRMOPublicReport, org_id, report_id)
|
||||
}
|
||||
func PublicReportsForOrganization(ctx context.Context, org_id int32, is_public bool) ([]*types.PublicReport, error) {
|
||||
return publicreport.ReportsForOrganization(ctx, org_id, is_public)
|
||||
func PublicReportsForOrganization(ctx context.Context, org_id int32, is_public bool) ([]types.PublicReport, error) {
|
||||
return publicreport.UnreviewedForOrganization(ctx, db.PGInstance.PGXPool, int64(org_id), is_public)
|
||||
}
|
||||
func PublicReportsFromIDs(ctx context.Context, report_ids []int64) ([]modelpublicreport.Report, error) {
|
||||
return querypublicreport.ReportsFromIDs(ctx, report_ids)
|
||||
|
|
|
|||
|
|
@ -6,9 +6,12 @@ import (
|
|||
|
||||
"github.com/Gleipnir-Technology/bob"
|
||||
"github.com/Gleipnir-Technology/bob/dialect/psql"
|
||||
"github.com/Gleipnir-Technology/bob/dialect/psql/dialect"
|
||||
"github.com/Gleipnir-Technology/bob/dialect/psql/sm"
|
||||
"github.com/Gleipnir-Technology/nidus-sync/db"
|
||||
querypublic "github.com/Gleipnir-Technology/nidus-sync/db/query/public"
|
||||
querypublicreport "github.com/Gleipnir-Technology/nidus-sync/db/query/publicreport"
|
||||
modelpublic "github.com/Gleipnir-Technology/nidus-sync/db/gen/nidus-sync/public/model"
|
||||
modelpublicreport "github.com/Gleipnir-Technology/nidus-sync/db/gen/nidus-sync/publicreport/model"
|
||||
"github.com/Gleipnir-Technology/nidus-sync/platform/types"
|
||||
//"github.com/google/uuid"
|
||||
"github.com/rs/zerolog/log"
|
||||
|
|
@ -45,20 +48,22 @@ func ByIDWater(ctx context.Context, public_id string, is_public bool) (*types.Pu
|
|||
}
|
||||
return water(ctx, public_id, *report)
|
||||
}
|
||||
func ReportsForOrganization(ctx context.Context, org_id int32, is_public bool) ([]*types.PublicReport, error) {
|
||||
query := reportQuery()
|
||||
query.Apply(
|
||||
sm.Where(psql.Quote("r", "organization_id").EQ(psql.Arg(org_id))),
|
||||
sm.Where(psql.Quote("r", "reviewed").IsNull()),
|
||||
)
|
||||
return reportQueryToRows(ctx, query, is_public)
|
||||
func UnreviewedForOrganization(ctx context.Context, txn db.Ex, org_id int64, is_public bool) ([]types.PublicReport, error) {
|
||||
reports, err := querypublicreport.ReportsUnreviewedForOrganization(ctx, txn, org_id)
|
||||
if err != nil {
|
||||
return nil, fmt.Errorf("reports unreviewed: %w", err)
|
||||
}
|
||||
return reportQueryToRows(ctx, reports, is_public)
|
||||
}
|
||||
func byID(ctx context.Context, public_id string, is_public bool) (*types.PublicReport, error) {
|
||||
query := reportQuery()
|
||||
query.Apply(
|
||||
sm.Where(psql.Quote("r", "public_id").EQ(psql.Arg(public_id))),
|
||||
)
|
||||
reports, err := reportQueryToRows(ctx, query, is_public)
|
||||
report, err := querypublicreport.ReportFromPublicID(ctx, db.PGInstance.PGXPool, public_id)
|
||||
if err != nil {
|
||||
return nil, fmt.Errorf("query report from public ID: %w", err)
|
||||
}
|
||||
if report == nil {
|
||||
return nil, nil
|
||||
}
|
||||
reports, err := reportQueryToRows(ctx, []modelpublicreport.Report{*report}, is_public)
|
||||
if err != nil {
|
||||
return nil, fmt.Errorf("query to rows: %w", err)
|
||||
}
|
||||
|
|
@ -66,17 +71,16 @@ func byID(ctx context.Context, public_id string, is_public bool) (*types.PublicR
|
|||
if len(reports) != 1 {
|
||||
return nil, nil
|
||||
}
|
||||
return reports[0], nil
|
||||
return &reports[0], nil
|
||||
}
|
||||
func reportQueryToRows(ctx context.Context, query bob.BaseQuery[*dialect.SelectQuery], is_public bool) ([]*types.PublicReport, error) {
|
||||
rows, err := bob.All(ctx, db.PGInstance.BobDB, query, scan.StructMapper[types.PublicReport]())
|
||||
|
||||
if err != nil {
|
||||
return nil, fmt.Errorf("get reports: %w", err)
|
||||
func reportQueryToRows(ctx context.Context, reports []modelpublicreport.Report, is_public bool) ([]types.PublicReport, error) {
|
||||
address_ids := make([]int64, 0)
|
||||
report_ids := make([]int32, len(reports))
|
||||
for i, report := range reports {
|
||||
report_ids[i] = report.ID
|
||||
if report.AddressID != nil {
|
||||
address_ids = append(address_ids, int64(*report.AddressID))
|
||||
}
|
||||
report_ids := make([]int32, len(rows))
|
||||
for i, row := range rows {
|
||||
report_ids[i] = row.ID
|
||||
}
|
||||
images_by_id, err := loadImagesForReport(ctx, report_ids)
|
||||
if err != nil {
|
||||
|
|
@ -86,31 +90,74 @@ func reportQueryToRows(ctx context.Context, query bob.BaseQuery[*dialect.SelectQ
|
|||
if err != nil {
|
||||
return nil, fmt.Errorf("log entries for reports: %w", err)
|
||||
}
|
||||
addresses, err := querypublic.AddressesFromIDs(ctx, db.PGInstance.PGXPool, address_ids)
|
||||
if err != nil {
|
||||
return nil, fmt.Errorf("addresses for reports: %w", err)
|
||||
}
|
||||
addresses_by_id := make(map[int64]modelpublic.Address, 0)
|
||||
for _, address := range addresses {
|
||||
addresses_by_id[int64(address.ID)] = address
|
||||
}
|
||||
|
||||
results := make([]*types.PublicReport, len(rows))
|
||||
for i, row := range rows {
|
||||
results := make([]types.PublicReport, len(reports))
|
||||
for i, row := range reports {
|
||||
var images []types.Image
|
||||
images, ok := images_by_id[row.ID]
|
||||
if ok {
|
||||
row.Images = images
|
||||
} else {
|
||||
row.Images = []types.Image{}
|
||||
if !ok {
|
||||
images = []types.Image{}
|
||||
}
|
||||
row.Log = logs_by_report_id[row.ID]
|
||||
if row.Location.Latitude == 0.0 || row.Location.Longitude == 0.0 {
|
||||
row.Location = nil
|
||||
logs, ok := logs_by_report_id[row.ID]
|
||||
if !ok {
|
||||
return nil, fmt.Errorf("impossible, missing logs for %d", row.ID)
|
||||
}
|
||||
var location *types.Location
|
||||
if row.Location == nil {
|
||||
location = nil
|
||||
}
|
||||
var address *types.Address
|
||||
if row.AddressID != nil {
|
||||
addr, ok := addresses_by_id[int64(*row.AddressID)]
|
||||
if !ok {
|
||||
return nil, fmt.Errorf("impossible, missing address %d", row.AddressID)
|
||||
}
|
||||
a := types.AddressFromModel(addr)
|
||||
address = &a
|
||||
}
|
||||
if address == nil {
|
||||
return nil, fmt.Errorf("nil address: %w", err)
|
||||
}
|
||||
results[i] = types.PublicReport{
|
||||
Address: *address,
|
||||
Concerns: nil,
|
||||
Created: row.Created,
|
||||
ID: row.ID,
|
||||
Images: images,
|
||||
Location: location,
|
||||
Log: logs,
|
||||
DistrictID: &row.OrganizationID,
|
||||
District: nil,
|
||||
PublicID: row.PublicID,
|
||||
Reporter: types.Contact{
|
||||
CanSMS: &row.ReporterPhoneCanSms,
|
||||
Email: &row.ReporterEmail,
|
||||
HasEmail: row.ReporterEmail != "",
|
||||
HasPhone: row.ReporterPhone != "",
|
||||
Name: &row.ReporterName,
|
||||
Phone: &row.ReporterPhone,
|
||||
},
|
||||
Status: row.Status.String(),
|
||||
Type: row.ReportType.String(),
|
||||
URI: "",
|
||||
}
|
||||
row.Address.Raw = types.AddressToRaw(row.Address)
|
||||
results[i] = &row
|
||||
}
|
||||
return results, nil
|
||||
}
|
||||
func Reports(ctx context.Context, org_id int32, ids []int32, is_public bool) ([]*types.PublicReport, error) {
|
||||
query := reportQuery()
|
||||
query.Apply(
|
||||
sm.Where(psql.Quote("r", "organization_id").EQ(psql.Arg(org_id))),
|
||||
sm.Where(psql.Quote("r", "id").EQ(psql.Any(ids))),
|
||||
)
|
||||
return reportQueryToRows(ctx, query, is_public)
|
||||
func Reports(ctx context.Context, org_id int64, ids []int64, is_public bool) ([]types.PublicReport, error) {
|
||||
reports, err := querypublicreport.ReportsFromIDsForOrg(ctx, db.PGInstance.PGXPool, ids, org_id)
|
||||
if err != nil {
|
||||
return []types.PublicReport{}, fmt.Errorf("reports from ID for org: %w", err)
|
||||
}
|
||||
return reportQueryToRows(ctx, reports, is_public)
|
||||
}
|
||||
func ReportsForOrganizationCount(ctx context.Context, org_id int32) (uint, error) {
|
||||
type _Row struct {
|
||||
|
|
@ -143,38 +190,3 @@ func copyReportContent(src types.PublicReport, dst *types.PublicReport) {
|
|||
dst.Type = src.Type
|
||||
dst.URI = src.URI
|
||||
}
|
||||
func reportQuery() bob.BaseQuery[*dialect.SelectQuery] {
|
||||
return psql.Select(
|
||||
sm.Columns(
|
||||
"COALESCE(a.country, '') AS \"address.country\"",
|
||||
"a.id AS \"address.id\"",
|
||||
"COALESCE(a.gid, '') AS \"address.gid\"",
|
||||
"COALESCE(a.location_latitude, 0) AS \"address.location.latitude\"",
|
||||
"COALESCE(a.location_longitude, 0) AS \"address.location.longitude\"",
|
||||
"COALESCE(a.locality, '') AS \"address.locality\"",
|
||||
"COALESCE(a.number_, '') AS \"address.number_\"",
|
||||
"COALESCE(a.postal_code, '') AS \"address.postal_code\"",
|
||||
"COALESCE(a.region, '') AS \"address.region\"",
|
||||
"COALESCE(a.street, '') AS \"address.street\"",
|
||||
"r.address_raw AS \"address.raw\"",
|
||||
"r.created",
|
||||
"r.id",
|
||||
"r.latlng_accuracy_value AS \"location.accuracy\"",
|
||||
"COALESCE(ST_Y(r.location::geometry::geometry(point, 4326)), 0.0) AS \"location.latitude\"",
|
||||
"COALESCE(ST_X(r.location::geometry::geometry(point, 4326)), 0.0) AS \"location.longitude\"",
|
||||
"r.organization_id",
|
||||
"r.public_id",
|
||||
"r.report_type",
|
||||
"r.reporter_email AS \"reporter.email\"",
|
||||
"r.reporter_name AS \"reporter.name\"",
|
||||
"r.reporter_phone AS \"reporter.phone\"",
|
||||
"r.reporter_phone_can_sms AS \"reporter.can_sms\"",
|
||||
"r.status",
|
||||
),
|
||||
sm.From("publicreport.report").As("r"),
|
||||
sm.LeftJoin("address").As("a").OnEQ(
|
||||
psql.Quote("r", "address_id"),
|
||||
psql.Quote("a", "id"),
|
||||
),
|
||||
)
|
||||
}
|
||||
|
|
|
|||
|
|
@ -212,11 +212,11 @@ func SignalList(ctx context.Context, user User, limit int) ([]*Signal, error) {
|
|||
if err != nil {
|
||||
return nil, fmt.Errorf("failed to get signals: %w", err)
|
||||
}
|
||||
report_ids := make([]int32, 0)
|
||||
report_ids := make([]int64, 0)
|
||||
pool_ids := make([]int32, 0)
|
||||
for _, row := range rows {
|
||||
if row.Report.ID != 0 {
|
||||
report_ids = append(report_ids, row.Report.ID)
|
||||
report_ids = append(report_ids, int64(row.Report.ID))
|
||||
} else if row.Pool.ID != 0 {
|
||||
pool_ids = append(pool_ids, row.Pool.ID)
|
||||
}
|
||||
|
|
@ -225,7 +225,7 @@ func SignalList(ctx context.Context, user User, limit int) ([]*Signal, error) {
|
|||
if err != nil {
|
||||
return nil, fmt.Errorf("getting pools by ID: %w", err)
|
||||
}
|
||||
reports, err := publicreport.Reports(ctx, org_id, report_ids, false)
|
||||
reports, err := publicreport.Reports(ctx, int64(org_id), report_ids, false)
|
||||
if err != nil {
|
||||
return nil, fmt.Errorf("getting reports by ID: %w", err)
|
||||
}
|
||||
|
|
@ -234,7 +234,7 @@ func SignalList(ctx context.Context, user User, limit int) ([]*Signal, error) {
|
|||
pool_map[pool.ID] = pool
|
||||
log.Debug().Int32("pool", pool.ID).Msg("Added to map")
|
||||
}
|
||||
report_map := make(map[int32]*types.PublicReport, len(report_ids))
|
||||
report_map := make(map[int32]types.PublicReport, len(report_ids))
|
||||
for _, report := range reports {
|
||||
report_map[report.ID] = report
|
||||
}
|
||||
|
|
@ -254,11 +254,8 @@ func SignalList(ctx context.Context, user User, limit int) ([]*Signal, error) {
|
|||
if !ok {
|
||||
return nil, fmt.Errorf("failed to get report %d for %d", row.Report.ID, row.ID)
|
||||
}
|
||||
if report == nil {
|
||||
return nil, fmt.Errorf("got nil for report %d for %d", row.Report.ID, row.ID)
|
||||
}
|
||||
row.Pool = nil
|
||||
row.Report = report
|
||||
row.Report = &report
|
||||
} else {
|
||||
log.Debug().Int32("id", row.ID).Msg("has no publicrreport nor pool")
|
||||
row.Pool = nil
|
||||
|
|
|
|||
Loading…
Add table
Add a link
Reference in a new issue