Files
cmr-mini/backend/internal/store/postgres/map_experience_store.go

217 lines
6.1 KiB
Go

package postgres
import (
"context"
"fmt"
)
type MapExperienceRow struct {
PlacePublicID string
PlaceName string
MapAssetPublicID string
MapAssetName string
MapCoverURL *string
MapSummary *string
TileBaseURL *string
TileMetaURL *string
EventPublicID *string
EventDisplayName *string
EventSummary *string
EventStatus *string
EventIsDefaultExperience bool
EventShowInEventList bool
EventReleasePayloadJSON *string
EventPresentationID *string
EventPresentationName *string
EventPresentationType *string
EventPresentationSchema *string
EventContentBundleID *string
EventContentBundleName *string
EventContentEntryURL *string
EventContentAssetRootURL *string
EventContentMetadataJSON *string
}
func (s *Store) ListMapExperienceRows(ctx context.Context, limit int) ([]MapExperienceRow, error) {
if limit <= 0 || limit > 200 {
limit = 50
}
rows, err := s.pool.Query(ctx, `
SELECT
p.place_public_id,
p.name,
ma.map_asset_public_id,
ma.name,
COALESCE(ma.cover_url, p.cover_url) AS cover_url,
COALESCE(ma.description, p.description) AS summary,
tr.tile_base_url,
tr.meta_url,
e.event_public_id,
e.display_name,
e.summary,
e.status,
COALESCE(e.is_default_experience, false),
COALESCE(e.show_in_event_list, true),
er.payload_jsonb::text,
ep.presentation_public_id,
ep.name,
ep.presentation_type,
ep.schema_jsonb::text,
cb.content_bundle_public_id,
cb.name,
cb.entry_url,
cb.asset_root_url,
cb.metadata_jsonb::text
FROM map_assets ma
JOIN places p ON p.id = ma.place_id
LEFT JOIN tile_releases tr ON tr.id = ma.current_tile_release_id
LEFT JOIN map_runtime_bindings mrb
ON mrb.map_asset_id = ma.id
AND mrb.status = 'active'
LEFT JOIN event_releases er
ON er.runtime_binding_id = mrb.id
AND er.status = 'published'
LEFT JOIN events e
ON e.current_release_id = er.id
AND e.status = 'active'
LEFT JOIN event_presentations ep ON ep.id = er.presentation_id
LEFT JOIN content_bundles cb ON cb.id = er.content_bundle_id
WHERE ma.status = 'active'
AND (e.id IS NULL OR e.show_in_event_list = true)
ORDER BY p.name ASC, ma.name ASC, COALESCE(e.is_default_experience, false) DESC, e.display_name ASC
LIMIT $1
`, limit)
if err != nil {
return nil, fmt.Errorf("list map experience rows: %w", err)
}
defer rows.Close()
items := make([]MapExperienceRow, 0, limit)
for rows.Next() {
var item MapExperienceRow
if err := rows.Scan(
&item.PlacePublicID,
&item.PlaceName,
&item.MapAssetPublicID,
&item.MapAssetName,
&item.MapCoverURL,
&item.MapSummary,
&item.TileBaseURL,
&item.TileMetaURL,
&item.EventPublicID,
&item.EventDisplayName,
&item.EventSummary,
&item.EventStatus,
&item.EventIsDefaultExperience,
&item.EventShowInEventList,
&item.EventReleasePayloadJSON,
&item.EventPresentationID,
&item.EventPresentationName,
&item.EventPresentationType,
&item.EventPresentationSchema,
&item.EventContentBundleID,
&item.EventContentBundleName,
&item.EventContentEntryURL,
&item.EventContentAssetRootURL,
&item.EventContentMetadataJSON,
); err != nil {
return nil, fmt.Errorf("scan map experience row: %w", err)
}
items = append(items, item)
}
if err := rows.Err(); err != nil {
return nil, fmt.Errorf("iterate map experience rows: %w", err)
}
return items, nil
}
func (s *Store) ListMapExperienceRowsByMapPublicID(ctx context.Context, mapAssetPublicID string) ([]MapExperienceRow, error) {
rows, err := s.pool.Query(ctx, `
SELECT
p.place_public_id,
p.name,
ma.map_asset_public_id,
ma.name,
COALESCE(ma.cover_url, p.cover_url) AS cover_url,
COALESCE(ma.description, p.description) AS summary,
tr.tile_base_url,
tr.meta_url,
e.event_public_id,
e.display_name,
e.summary,
e.status,
COALESCE(e.is_default_experience, false),
COALESCE(e.show_in_event_list, true),
er.payload_jsonb::text,
ep.presentation_public_id,
ep.name,
ep.presentation_type,
ep.schema_jsonb::text,
cb.content_bundle_public_id,
cb.name,
cb.entry_url,
cb.asset_root_url,
cb.metadata_jsonb::text
FROM map_assets ma
JOIN places p ON p.id = ma.place_id
LEFT JOIN tile_releases tr ON tr.id = ma.current_tile_release_id
LEFT JOIN map_runtime_bindings mrb
ON mrb.map_asset_id = ma.id
AND mrb.status = 'active'
LEFT JOIN event_releases er
ON er.runtime_binding_id = mrb.id
AND er.status = 'published'
LEFT JOIN events e
ON e.current_release_id = er.id
AND e.status = 'active'
LEFT JOIN event_presentations ep ON ep.id = er.presentation_id
LEFT JOIN content_bundles cb ON cb.id = er.content_bundle_id
WHERE ma.map_asset_public_id = $1
AND ma.status = 'active'
AND (e.id IS NULL OR e.show_in_event_list = true)
ORDER BY COALESCE(e.is_default_experience, false) DESC, e.display_name ASC
`, mapAssetPublicID)
if err != nil {
return nil, fmt.Errorf("list map experience rows by map public id: %w", err)
}
defer rows.Close()
items := make([]MapExperienceRow, 0, 8)
for rows.Next() {
var item MapExperienceRow
if err := rows.Scan(
&item.PlacePublicID,
&item.PlaceName,
&item.MapAssetPublicID,
&item.MapAssetName,
&item.MapCoverURL,
&item.MapSummary,
&item.TileBaseURL,
&item.TileMetaURL,
&item.EventPublicID,
&item.EventDisplayName,
&item.EventSummary,
&item.EventStatus,
&item.EventIsDefaultExperience,
&item.EventShowInEventList,
&item.EventReleasePayloadJSON,
&item.EventPresentationID,
&item.EventPresentationName,
&item.EventPresentationType,
&item.EventPresentationSchema,
&item.EventContentBundleID,
&item.EventContentBundleName,
&item.EventContentEntryURL,
&item.EventContentAssetRootURL,
&item.EventContentMetadataJSON,
); err != nil {
return nil, fmt.Errorf("scan map experience detail row: %w", err)
}
items = append(items, item)
}
if err := rows.Err(); err != nil {
return nil, fmt.Errorf("iterate map experience detail rows: %w", err)
}
return items, nil
}