Files
backend/internal/database/geospatial.sql.go
2025-12-13 22:34:01 +05:00

413 lines
12 KiB
Go
Raw Blame History

This file contains ambiguous Unicode characters

This file contains Unicode characters that might be confused with other characters. If you think that this is intentional, you can safely ignore this warning. Use the Escape button to reveal them.

// Code generated by sqlc. DO NOT EDIT.
// versions:
// sqlc v1.30.0
// source: geospatial.sql
package database
import (
"context"
"github.com/jackc/pgx/v5/pgtype"
)
const CountRequestsNearby = `-- name: CountRequestsNearby :one
SELECT COUNT(*) FROM requests r
WHERE r.deleted_at IS NULL
AND r.status = $3
AND ST_DWithin(
r.location,
ST_SetSRID(ST_MakePoint($1, $2), 4326)::geography,
$4
)
`
type CountRequestsNearbyParams struct {
StMakepoint interface{} `json:"st_makepoint"`
StMakepoint_2 interface{} `json:"st_makepoint_2"`
Status NullRequestStatus `json:"status"`
StDwithin interface{} `json:"st_dwithin"`
}
// ============================================================================
// Подсчет заявок поблизости
// ============================================================================
func (q *Queries) CountRequestsNearby(ctx context.Context, arg CountRequestsNearbyParams) (int64, error) {
row := q.db.QueryRow(ctx, CountRequestsNearby,
arg.StMakepoint,
arg.StMakepoint_2,
arg.Status,
arg.StDwithin,
)
var count int64
err := row.Scan(&count)
return count, err
}
const FindNearestRequestsForVolunteer = `-- name: FindNearestRequestsForVolunteer :many
SELECT
r.id,
r.title,
r.description,
r.urgency,
r.status,
r.created_at,
ST_Y(r.location::geometry) as latitude,
ST_X(r.location::geometry) as longitude,
ST_Distance(
r.location,
(SELECT u.location FROM users u WHERE u.id = $1)
) as distance_meters,
rt.name as request_type_name,
rt.icon as request_type_icon
FROM requests r
JOIN request_types rt ON rt.id = r.request_type_id
WHERE r.deleted_at IS NULL
AND r.status = 'approved'
AND r.assigned_volunteer_id IS NULL
AND ST_DWithin(
r.location,
(SELECT u.location FROM users u WHERE u.id = $1),
$2
)
ORDER BY
CASE r.urgency
WHEN 'urgent' THEN 1
WHEN 'high' THEN 2
WHEN 'medium' THEN 3
ELSE 4
END,
distance_meters
LIMIT $3
`
type FindNearestRequestsForVolunteerParams struct {
ID int64 `json:"id"`
StDwithin interface{} `json:"st_dwithin"`
Limit int32 `json:"limit"`
}
type FindNearestRequestsForVolunteerRow struct {
ID int64 `json:"id"`
Title string `json:"title"`
Description string `json:"description"`
Urgency pgtype.Text `json:"urgency"`
Status NullRequestStatus `json:"status"`
CreatedAt pgtype.Timestamptz `json:"created_at"`
Latitude interface{} `json:"latitude"`
Longitude interface{} `json:"longitude"`
DistanceMeters interface{} `json:"distance_meters"`
RequestTypeName string `json:"request_type_name"`
RequestTypeIcon pgtype.Text `json:"request_type_icon"`
}
// ============================================================================
// Поиск ближайших заявок для волонтера
// ============================================================================
func (q *Queries) FindNearestRequestsForVolunteer(ctx context.Context, arg FindNearestRequestsForVolunteerParams) ([]FindNearestRequestsForVolunteerRow, error) {
rows, err := q.db.Query(ctx, FindNearestRequestsForVolunteer, arg.ID, arg.StDwithin, arg.Limit)
if err != nil {
return nil, err
}
defer rows.Close()
items := []FindNearestRequestsForVolunteerRow{}
for rows.Next() {
var i FindNearestRequestsForVolunteerRow
if err := rows.Scan(
&i.ID,
&i.Title,
&i.Description,
&i.Urgency,
&i.Status,
&i.CreatedAt,
&i.Latitude,
&i.Longitude,
&i.DistanceMeters,
&i.RequestTypeName,
&i.RequestTypeIcon,
); err != nil {
return nil, err
}
items = append(items, i)
}
if err := rows.Err(); err != nil {
return nil, err
}
return items, nil
}
const FindRequestsInBounds = `-- name: FindRequestsInBounds :many
SELECT
r.id,
r.title,
r.urgency,
r.status,
r.created_at,
ST_Y(r.location::geometry) as latitude,
ST_X(r.location::geometry) as longitude,
rt.icon as request_type_icon,
rt.name as request_type_name
FROM requests r
JOIN request_types rt ON rt.id = r.request_type_id
WHERE r.deleted_at IS NULL
AND r.status::text = ANY($1::text[])
AND ST_Within(
r.location::geometry,
ST_MakeEnvelope($2, $3, $4, $5, 4326)
)
ORDER BY r.created_at DESC
LIMIT 200
`
type FindRequestsInBoundsParams struct {
Column1 []string `json:"column_1"`
StMakeenvelope interface{} `json:"st_makeenvelope"`
StMakeenvelope_2 interface{} `json:"st_makeenvelope_2"`
StMakeenvelope_3 interface{} `json:"st_makeenvelope_3"`
StMakeenvelope_4 interface{} `json:"st_makeenvelope_4"`
}
type FindRequestsInBoundsRow struct {
ID int64 `json:"id"`
Title string `json:"title"`
Urgency pgtype.Text `json:"urgency"`
Status NullRequestStatus `json:"status"`
CreatedAt pgtype.Timestamptz `json:"created_at"`
Latitude interface{} `json:"latitude"`
Longitude interface{} `json:"longitude"`
RequestTypeIcon pgtype.Text `json:"request_type_icon"`
RequestTypeName string `json:"request_type_name"`
}
// ============================================================================
// Поиск заявок в прямоугольной области (для карты)
// ============================================================================
func (q *Queries) FindRequestsInBounds(ctx context.Context, arg FindRequestsInBoundsParams) ([]FindRequestsInBoundsRow, error) {
rows, err := q.db.Query(ctx, FindRequestsInBounds,
arg.Column1,
arg.StMakeenvelope,
arg.StMakeenvelope_2,
arg.StMakeenvelope_3,
arg.StMakeenvelope_4,
)
if err != nil {
return nil, err
}
defer rows.Close()
items := []FindRequestsInBoundsRow{}
for rows.Next() {
var i FindRequestsInBoundsRow
if err := rows.Scan(
&i.ID,
&i.Title,
&i.Urgency,
&i.Status,
&i.CreatedAt,
&i.Latitude,
&i.Longitude,
&i.RequestTypeIcon,
&i.RequestTypeName,
); err != nil {
return nil, err
}
items = append(items, i)
}
if err := rows.Err(); err != nil {
return nil, err
}
return items, nil
}
const FindRequestsNearby = `-- name: FindRequestsNearby :many
SELECT
r.id,
r.title,
r.description,
r.address,
r.city,
r.urgency,
r.status,
r.created_at,
r.desired_completion_date,
ST_Y(r.location::geometry) as latitude,
ST_X(r.location::geometry) as longitude,
ST_Distance(
r.location,
ST_SetSRID(ST_MakePoint($1, $2), 4326)::geography
) as distance_meters,
rt.name as request_type_name,
rt.icon as request_type_icon,
(u.first_name || ' ' || u.last_name) as requester_name
FROM requests r
JOIN request_types rt ON rt.id = r.request_type_id
JOIN users u ON u.id = r.requester_id
WHERE r.deleted_at IS NULL
AND r.status::text = ANY($3::text[])
AND ST_DWithin(
r.location,
ST_SetSRID(ST_MakePoint($1, $2), 4326)::geography,
$4
)
ORDER BY distance_meters
LIMIT $5 OFFSET $6
`
type FindRequestsNearbyParams struct {
StMakepoint interface{} `json:"st_makepoint"`
StMakepoint_2 interface{} `json:"st_makepoint_2"`
Column3 []string `json:"column_3"`
StDwithin interface{} `json:"st_dwithin"`
Limit int32 `json:"limit"`
Offset int32 `json:"offset"`
}
type FindRequestsNearbyRow struct {
ID int64 `json:"id"`
Title string `json:"title"`
Description string `json:"description"`
Address string `json:"address"`
City pgtype.Text `json:"city"`
Urgency pgtype.Text `json:"urgency"`
Status NullRequestStatus `json:"status"`
CreatedAt pgtype.Timestamptz `json:"created_at"`
DesiredCompletionDate pgtype.Timestamptz `json:"desired_completion_date"`
Latitude interface{} `json:"latitude"`
Longitude interface{} `json:"longitude"`
DistanceMeters interface{} `json:"distance_meters"`
RequestTypeName string `json:"request_type_name"`
RequestTypeIcon pgtype.Text `json:"request_type_icon"`
RequesterName interface{} `json:"requester_name"`
}
// Фаза 2B: Геопространственные запросы (ВЫСОКИЙ ПРИОРИТЕТ)
// PostGIS запросы для поиска заявок по геолокации
// ============================================================================
// Поиск заявок рядом с точкой
// ============================================================================
func (q *Queries) FindRequestsNearby(ctx context.Context, arg FindRequestsNearbyParams) ([]FindRequestsNearbyRow, error) {
rows, err := q.db.Query(ctx, FindRequestsNearby,
arg.StMakepoint,
arg.StMakepoint_2,
arg.Column3,
arg.StDwithin,
arg.Limit,
arg.Offset,
)
if err != nil {
return nil, err
}
defer rows.Close()
items := []FindRequestsNearbyRow{}
for rows.Next() {
var i FindRequestsNearbyRow
if err := rows.Scan(
&i.ID,
&i.Title,
&i.Description,
&i.Address,
&i.City,
&i.Urgency,
&i.Status,
&i.CreatedAt,
&i.DesiredCompletionDate,
&i.Latitude,
&i.Longitude,
&i.DistanceMeters,
&i.RequestTypeName,
&i.RequestTypeIcon,
&i.RequesterName,
); err != nil {
return nil, err
}
items = append(items, i)
}
if err := rows.Err(); err != nil {
return nil, err
}
return items, nil
}
const FindVolunteersNearRequest = `-- name: FindVolunteersNearRequest :many
SELECT
u.id,
(u.first_name || ' ' || u.last_name) as full_name,
u.avatar_url,
u.volunteer_rating,
u.completed_requests_count,
ST_Y(u.location::geometry) as latitude,
ST_X(u.location::geometry) as longitude,
ST_Distance(
u.location,
(SELECT req.location FROM requests req WHERE req.id = $1)
) as distance_meters
FROM users u
JOIN user_roles ur ON ur.user_id = u.id
JOIN roles r ON r.id = ur.role_id
WHERE r.name = 'volunteer'
AND u.deleted_at IS NULL
AND u.is_blocked = FALSE
AND u.location IS NOT NULL
AND ST_DWithin(
u.location,
(SELECT req.location FROM requests req WHERE req.id = $1),
$2
)
ORDER BY distance_meters
LIMIT $3
`
type FindVolunteersNearRequestParams struct {
ID int64 `json:"id"`
StDwithin interface{} `json:"st_dwithin"`
Limit int32 `json:"limit"`
}
type FindVolunteersNearRequestRow struct {
ID int64 `json:"id"`
FullName interface{} `json:"full_name"`
AvatarUrl pgtype.Text `json:"avatar_url"`
VolunteerRating pgtype.Numeric `json:"volunteer_rating"`
CompletedRequestsCount pgtype.Int4 `json:"completed_requests_count"`
Latitude interface{} `json:"latitude"`
Longitude interface{} `json:"longitude"`
DistanceMeters interface{} `json:"distance_meters"`
}
// ============================================================================
// Поиск волонтеров рядом с заявкой
// ============================================================================
func (q *Queries) FindVolunteersNearRequest(ctx context.Context, arg FindVolunteersNearRequestParams) ([]FindVolunteersNearRequestRow, error) {
rows, err := q.db.Query(ctx, FindVolunteersNearRequest, arg.ID, arg.StDwithin, arg.Limit)
if err != nil {
return nil, err
}
defer rows.Close()
items := []FindVolunteersNearRequestRow{}
for rows.Next() {
var i FindVolunteersNearRequestRow
if err := rows.Scan(
&i.ID,
&i.FullName,
&i.AvatarUrl,
&i.VolunteerRating,
&i.CompletedRequestsCount,
&i.Latitude,
&i.Longitude,
&i.DistanceMeters,
); err != nil {
return nil, err
}
items = append(items, i)
}
if err := rows.Err(); err != nil {
return nil, err
}
return items, nil
}