mirror of
https://github.com/IS1DI/x0gp.git
synced 2026-07-16 20:47:55 +00:00
feat(server): initial implementation
This commit captures the full server code accumulated across
several development sessions. It includes the following layers,
applied in roughly this order during development:
1. Base infrastructure
- cmd/poc-server HTTP+WebSocket server, /health, /stats
- internal/transport wire types (Envelope + all message types)
- internal/catalog, internal/realtime, internal/stats
- internal/storage/postgres with migrations 001-004
- .env, .env.example, docker-compose, Dockerfile, scripts/
2. Swagger documentation
- go get github.com/swaggo/http-swagger
- swag init produces docs/docs.go
- /swagger/index.html UI, /swagger/doc.json spec
- annotations on health/stats/ws and catalog handlers
3. Races API
- internal/races/{store,service,keyset,types}.go
- migration 005_races.sql: finished_races, race_plans, race_queue
- GET /api/races with keyset pagination, status filter
- GET /api/races/upcoming
- POST /api/races/queue/join, GET, DELETE
- POST/GET /api/races/plans, DELETE /{id}
- lobby.RaceMeta simplification (no host_id/host_name)
4. Races seeder
- internal/races/seed with deterministic generator
- --seed-races / --reset CLI flags in main.go
- 30 finished + 5 live + 5 plans + 4 queue entries
5. Drivers and clans
- internal/drivers, internal/clans (CRUD, validation)
- migration 008_drivers_clans.sql
- /api/clans and /api/drivers endpoints
- 3-letter uppercase nickname/tag validation
- lobby.DriverMeta: Nickname, AvatarURL, ClanID, ClanTag
6. Podium
- internal/transport.RacePodiumEntry
- lobby.SetDriverProfile for in-memory metadata sync
- migration 007_podium.sql (podium JSONB column)
- seeder populates top-3 per finished race
7. Live races persistence
- migration 009_live_persistence.sql: live_races,
live_race_drivers, lobby_drivers
- internal/races/live_store.go: LiveStore with write-side
mirror for lobby.Service mutations
- Service.collectLive and Upcoming read from Postgres
- main.go RestoreFromDB rehydrates lobby on startup
8. Unify live + finished into one races table
- migration 010_unify_races.sql: rename finished_races to
races, expand status CHECK, merge live rows
- PgStore now hosts both write paths; LiveStore is a
thin facade implementing lobby.Persistence
- seeder resetAll drops only finished/cancelled rows and
race_plans / race_queue / lobby_drivers
Each layer is consistent on its own; cross-layer changes are
visible in the file history. A future refactor may split this
commit into the per-stage boundaries listed above.
This commit is contained in:
@@ -0,0 +1,116 @@
|
||||
-- 001_init.sql — initial schema for x0gp catalog.
|
||||
--
|
||||
-- Tables:
|
||||
-- tracks static track definitions (oval, figure-eight, etc.)
|
||||
-- track_waypoints racing line samples (1-to-many with tracks)
|
||||
-- track_tags many-to-many tags for tracks
|
||||
-- cars car definitions (chassis, motor, battery, etc.)
|
||||
--
|
||||
-- TimescaleDB extension is enabled opportunistically — not required for the
|
||||
-- catalog itself; the telemetry hypertable will be added in a later phase
|
||||
-- (S2). We enable it here so that the extension is provisioned alongside
|
||||
-- the base schema.
|
||||
|
||||
CREATE EXTENSION IF NOT EXISTS timescaledb;
|
||||
|
||||
-- ---------------------------------------------------------------------------
|
||||
-- Tracks
|
||||
-- ---------------------------------------------------------------------------
|
||||
|
||||
CREATE TABLE IF NOT EXISTS tracks (
|
||||
id TEXT PRIMARY KEY,
|
||||
name TEXT NOT NULL,
|
||||
description TEXT NOT NULL DEFAULT '',
|
||||
author_id TEXT NOT NULL DEFAULT 'system',
|
||||
visibility TEXT NOT NULL DEFAULT 'system'
|
||||
CHECK (visibility IN ('system', 'public', 'private')),
|
||||
scale INT NOT NULL DEFAULT 27,
|
||||
length_m DOUBLE PRECISION NOT NULL DEFAULT 0,
|
||||
width_m DOUBLE PRECISION NOT NULL DEFAULT 0,
|
||||
lane_width_m DOUBLE PRECISION NOT NULL DEFAULT 0.20,
|
||||
surface TEXT NOT NULL DEFAULT 'carpet'
|
||||
CHECK (surface IN ('carpet', 'tile', 'wood', 'paper', 'mixed')),
|
||||
best_lap_ms BIGINT NOT NULL DEFAULT 0,
|
||||
best_lap_holder TEXT NOT NULL DEFAULT '',
|
||||
bounds_min_x DOUBLE PRECISION NOT NULL DEFAULT 0,
|
||||
bounds_min_y DOUBLE PRECISION NOT NULL DEFAULT 0,
|
||||
bounds_max_x DOUBLE PRECISION NOT NULL DEFAULT 0,
|
||||
bounds_max_y DOUBLE PRECISION NOT NULL DEFAULT 0,
|
||||
created_ms BIGINT NOT NULL,
|
||||
updated_ms BIGINT NOT NULL
|
||||
);
|
||||
|
||||
CREATE INDEX IF NOT EXISTS tracks_visibility_idx ON tracks (visibility);
|
||||
CREATE INDEX IF NOT EXISTS tracks_author_idx ON tracks (author_id);
|
||||
|
||||
CREATE TABLE IF NOT EXISTS track_waypoints (
|
||||
track_id TEXT NOT NULL REFERENCES tracks(id) ON DELETE CASCADE,
|
||||
seq INT NOT NULL,
|
||||
x DOUBLE PRECISION NOT NULL,
|
||||
y DOUBLE PRECISION NOT NULL,
|
||||
heading_rad DOUBLE PRECISION NOT NULL,
|
||||
speed_ms DOUBLE PRECISION NOT NULL,
|
||||
curvature DOUBLE PRECISION NOT NULL,
|
||||
PRIMARY KEY (track_id, seq)
|
||||
);
|
||||
|
||||
CREATE TABLE IF NOT EXISTS track_tags (
|
||||
track_id TEXT NOT NULL REFERENCES tracks(id) ON DELETE CASCADE,
|
||||
tag TEXT NOT NULL,
|
||||
PRIMARY KEY (track_id, tag)
|
||||
);
|
||||
|
||||
CREATE INDEX IF NOT EXISTS track_tags_tag_idx ON track_tags (tag);
|
||||
|
||||
-- ---------------------------------------------------------------------------
|
||||
-- Cars
|
||||
-- ---------------------------------------------------------------------------
|
||||
|
||||
CREATE TABLE IF NOT EXISTS cars (
|
||||
id TEXT PRIMARY KEY,
|
||||
name TEXT NOT NULL,
|
||||
owner_id TEXT NOT NULL DEFAULT 'system',
|
||||
visibility TEXT NOT NULL DEFAULT 'system'
|
||||
CHECK (visibility IN ('system', 'public', 'private')),
|
||||
scale INT NOT NULL DEFAULT 27,
|
||||
|
||||
length_mm DOUBLE PRECISION NOT NULL,
|
||||
width_mm DOUBLE PRECISION NOT NULL,
|
||||
height_mm DOUBLE PRECISION NOT NULL DEFAULT 0,
|
||||
weight_g DOUBLE PRECISION NOT NULL DEFAULT 0,
|
||||
|
||||
chassis_model TEXT NOT NULL DEFAULT '',
|
||||
chassis_material TEXT NOT NULL DEFAULT '',
|
||||
chassis_printed BOOLEAN NOT NULL DEFAULT FALSE,
|
||||
chassis_wheelbase_mm DOUBLE PRECISION NOT NULL DEFAULT 0,
|
||||
chassis_track_mm DOUBLE PRECISION NOT NULL DEFAULT 0,
|
||||
|
||||
motor_kind TEXT NOT NULL DEFAULT 'brushed',
|
||||
motor_class TEXT NOT NULL DEFAULT '',
|
||||
motor_kv INT NOT NULL DEFAULT 0,
|
||||
motor_power_w DOUBLE PRECISION NOT NULL DEFAULT 0,
|
||||
|
||||
battery_voltage_v DOUBLE PRECISION NOT NULL DEFAULT 0,
|
||||
battery_capacity_mah INT NOT NULL DEFAULT 0,
|
||||
battery_cells INT NOT NULL DEFAULT 0,
|
||||
battery_chemistry TEXT NOT NULL DEFAULT 'li-po',
|
||||
|
||||
drive TEXT NOT NULL DEFAULT '2WD'
|
||||
CHECK (drive IN ('2WD', '4WD')),
|
||||
|
||||
top_speed_ms DOUBLE PRECISION NOT NULL DEFAULT 0,
|
||||
color_hex TEXT NOT NULL DEFAULT '#ff6b1a',
|
||||
avatar_url TEXT NOT NULL DEFAULT '',
|
||||
active BOOLEAN NOT NULL DEFAULT TRUE,
|
||||
|
||||
total_distance_m DOUBLE PRECISION NOT NULL DEFAULT 0,
|
||||
total_races INT NOT NULL DEFAULT 0,
|
||||
total_laps INT NOT NULL DEFAULT 0,
|
||||
best_lap_ms BIGINT NOT NULL DEFAULT 0,
|
||||
|
||||
created_ms BIGINT NOT NULL,
|
||||
updated_ms BIGINT NOT NULL
|
||||
);
|
||||
|
||||
CREATE INDEX IF NOT EXISTS cars_visibility_idx ON cars (visibility);
|
||||
CREATE INDEX IF NOT EXISTS cars_owner_idx ON cars (owner_id);
|
||||
@@ -0,0 +1,561 @@
|
||||
-- 002_seed.sql — initial system catalog (tracks + cars).
|
||||
-- Generated from internal/catalog/seeddefs via scripts/genseed.
|
||||
-- Idempotent: safe to re-apply (ON CONFLICT DO NOTHING).
|
||||
|
||||
INSERT INTO tracks (id, name, description, author_id, visibility, scale,
|
||||
length_m, width_m, lane_width_m, surface, best_lap_ms, best_lap_holder,
|
||||
bounds_min_x, bounds_min_y, bounds_max_x, bounds_max_y,
|
||||
created_ms, updated_ms)
|
||||
VALUES ('monaco', 'Monaco', 'Circuit de Monaco. Narrow street circuit, tight hairpins, no room for error.', 'system', 'system', 27,
|
||||
3.5500000000000003, 1.1, 0.18, 'tile', 0, 'Verstappen',
|
||||
0.4, 1.4, 3.95, 2.5,
|
||||
1700000000000, 1700000000000)
|
||||
ON CONFLICT (id) DO NOTHING;
|
||||
|
||||
INSERT INTO track_waypoints (track_id, seq, x, y, heading_rad, speed_ms, curvature)
|
||||
VALUES ('monaco', 0, 0.4, 2.2, 0, 3.2, 0)
|
||||
ON CONFLICT (track_id, seq) DO NOTHING;
|
||||
INSERT INTO track_waypoints (track_id, seq, x, y, heading_rad, speed_ms, curvature)
|
||||
VALUES ('monaco', 1, 1.1, 2.2, 0, 3, 0)
|
||||
ON CONFLICT (track_id, seq) DO NOTHING;
|
||||
INSERT INTO track_waypoints (track_id, seq, x, y, heading_rad, speed_ms, curvature)
|
||||
VALUES ('monaco', 2, 1.5, 2.05, -0.4, 2.4, 1.2)
|
||||
ON CONFLICT (track_id, seq) DO NOTHING;
|
||||
INSERT INTO track_waypoints (track_id, seq, x, y, heading_rad, speed_ms, curvature)
|
||||
VALUES ('monaco', 3, 1.7, 1.85, -0.9, 2.2, 1.8)
|
||||
ON CONFLICT (track_id, seq) DO NOTHING;
|
||||
INSERT INTO track_waypoints (track_id, seq, x, y, heading_rad, speed_ms, curvature)
|
||||
VALUES ('monaco', 4, 1.55, 1.55, -1.6, 2, 1.4)
|
||||
ON CONFLICT (track_id, seq) DO NOTHING;
|
||||
INSERT INTO track_waypoints (track_id, seq, x, y, heading_rad, speed_ms, curvature)
|
||||
VALUES ('monaco', 5, 1.25, 1.4, -2.4, 2.1, 1.2)
|
||||
ON CONFLICT (track_id, seq) DO NOTHING;
|
||||
INSERT INTO track_waypoints (track_id, seq, x, y, heading_rad, speed_ms, curvature)
|
||||
VALUES ('monaco', 6, 0.95, 1.55, 3.141592653589793, 1.9, 1.6)
|
||||
ON CONFLICT (track_id, seq) DO NOTHING;
|
||||
INSERT INTO track_waypoints (track_id, seq, x, y, heading_rad, speed_ms, curvature)
|
||||
VALUES ('monaco', 7, 0.75, 1.85, 2, 1.8, 2.2)
|
||||
ON CONFLICT (track_id, seq) DO NOTHING;
|
||||
INSERT INTO track_waypoints (track_id, seq, x, y, heading_rad, speed_ms, curvature)
|
||||
VALUES ('monaco', 8, 0.95, 2.15, 2.6, 1.8, 2.6)
|
||||
ON CONFLICT (track_id, seq) DO NOTHING;
|
||||
INSERT INTO track_waypoints (track_id, seq, x, y, heading_rad, speed_ms, curvature)
|
||||
VALUES ('monaco', 9, 1.2, 2.4, -2.8, 2.1, 1.4)
|
||||
ON CONFLICT (track_id, seq) DO NOTHING;
|
||||
INSERT INTO track_waypoints (track_id, seq, x, y, heading_rad, speed_ms, curvature)
|
||||
VALUES ('monaco', 10, 1.6, 2.5, -3, 2.4, 1)
|
||||
ON CONFLICT (track_id, seq) DO NOTHING;
|
||||
INSERT INTO track_waypoints (track_id, seq, x, y, heading_rad, speed_ms, curvature)
|
||||
VALUES ('monaco', 11, 2.6, 2.5, 0, 3.2, 0)
|
||||
ON CONFLICT (track_id, seq) DO NOTHING;
|
||||
INSERT INTO track_waypoints (track_id, seq, x, y, heading_rad, speed_ms, curvature)
|
||||
VALUES ('monaco', 12, 3.4, 2.5, 0, 3.2, 0)
|
||||
ON CONFLICT (track_id, seq) DO NOTHING;
|
||||
INSERT INTO track_waypoints (track_id, seq, x, y, heading_rad, speed_ms, curvature)
|
||||
VALUES ('monaco', 13, 3.6, 2.25, -0.5, 2.6, 1.5)
|
||||
ON CONFLICT (track_id, seq) DO NOTHING;
|
||||
INSERT INTO track_waypoints (track_id, seq, x, y, heading_rad, speed_ms, curvature)
|
||||
VALUES ('monaco', 14, 3.55, 1.95, 0.4, 2.6, 1.5)
|
||||
ON CONFLICT (track_id, seq) DO NOTHING;
|
||||
INSERT INTO track_waypoints (track_id, seq, x, y, heading_rad, speed_ms, curvature)
|
||||
VALUES ('monaco', 15, 3.3, 1.75, 1, 2.3, 1.4)
|
||||
ON CONFLICT (track_id, seq) DO NOTHING;
|
||||
INSERT INTO track_waypoints (track_id, seq, x, y, heading_rad, speed_ms, curvature)
|
||||
VALUES ('monaco', 16, 2.95, 1.55, 1.7, 2.1, 1.8)
|
||||
ON CONFLICT (track_id, seq) DO NOTHING;
|
||||
INSERT INTO track_waypoints (track_id, seq, x, y, heading_rad, speed_ms, curvature)
|
||||
VALUES ('monaco', 17, 2.6, 1.65, 2.6, 2.1, 1.8)
|
||||
ON CONFLICT (track_id, seq) DO NOTHING;
|
||||
INSERT INTO track_waypoints (track_id, seq, x, y, heading_rad, speed_ms, curvature)
|
||||
VALUES ('monaco', 18, 2.4, 1.9, -2.7, 2.3, 1.4)
|
||||
ON CONFLICT (track_id, seq) DO NOTHING;
|
||||
INSERT INTO track_waypoints (track_id, seq, x, y, heading_rad, speed_ms, curvature)
|
||||
VALUES ('monaco', 19, 2.4, 2.2, -3, 2.2, 1.6)
|
||||
ON CONFLICT (track_id, seq) DO NOTHING;
|
||||
INSERT INTO track_waypoints (track_id, seq, x, y, heading_rad, speed_ms, curvature)
|
||||
VALUES ('monaco', 20, 2.6, 2.4, 2.8, 2.5, 1)
|
||||
ON CONFLICT (track_id, seq) DO NOTHING;
|
||||
INSERT INTO track_waypoints (track_id, seq, x, y, heading_rad, speed_ms, curvature)
|
||||
VALUES ('monaco', 21, 3.2, 2.4, 0, 3.2, 0)
|
||||
ON CONFLICT (track_id, seq) DO NOTHING;
|
||||
INSERT INTO track_waypoints (track_id, seq, x, y, heading_rad, speed_ms, curvature)
|
||||
VALUES ('monaco', 22, 3.7, 2.4, 0, 3.2, 0)
|
||||
ON CONFLICT (track_id, seq) DO NOTHING;
|
||||
INSERT INTO track_waypoints (track_id, seq, x, y, heading_rad, speed_ms, curvature)
|
||||
VALUES ('monaco', 23, 3.95, 2.3, -0.3, 2.8, 0.8)
|
||||
ON CONFLICT (track_id, seq) DO NOTHING;
|
||||
|
||||
INSERT INTO track_tags (track_id, tag) VALUES ('monaco', 'f1')
|
||||
ON CONFLICT DO NOTHING;
|
||||
INSERT INTO track_tags (track_id, tag) VALUES ('monaco', 'street')
|
||||
ON CONFLICT DO NOTHING;
|
||||
INSERT INTO track_tags (track_id, tag) VALUES ('monaco', 'tight')
|
||||
ON CONFLICT DO NOTHING;
|
||||
INSERT INTO track_tags (track_id, tag) VALUES ('monaco', 'slow')
|
||||
ON CONFLICT DO NOTHING;
|
||||
INSERT INTO track_tags (track_id, tag) VALUES ('monaco', 'monaco')
|
||||
ON CONFLICT DO NOTHING;
|
||||
|
||||
INSERT INTO tracks (id, name, description, author_id, visibility, scale,
|
||||
length_m, width_m, lane_width_m, surface, best_lap_ms, best_lap_holder,
|
||||
bounds_min_x, bounds_min_y, bounds_max_x, bounds_max_y,
|
||||
created_ms, updated_ms)
|
||||
VALUES ('barcelona-catalunya', 'Barcelona-Catalunya', 'Circuit de Barcelona-Catalunya. Mix of high-speed corners and technical chicanes.', 'system', 'system', 27,
|
||||
3.75, 2.3000000000000003, 0.18, 'tile', 0, 'Verstappen',
|
||||
0.3, 0.4, 4.05, 2.7,
|
||||
1700000000000, 1700000000000)
|
||||
ON CONFLICT (id) DO NOTHING;
|
||||
|
||||
INSERT INTO track_waypoints (track_id, seq, x, y, heading_rad, speed_ms, curvature)
|
||||
VALUES ('barcelona-catalunya', 0, 0.3, 0.4, 0, 4.5, 0)
|
||||
ON CONFLICT (track_id, seq) DO NOTHING;
|
||||
INSERT INTO track_waypoints (track_id, seq, x, y, heading_rad, speed_ms, curvature)
|
||||
VALUES ('barcelona-catalunya', 1, 1.4, 0.4, 0, 4.5, 0)
|
||||
ON CONFLICT (track_id, seq) DO NOTHING;
|
||||
INSERT INTO track_waypoints (track_id, seq, x, y, heading_rad, speed_ms, curvature)
|
||||
VALUES ('barcelona-catalunya', 2, 1.7, 0.65, 1.5707963267948966, 2.2, 1.6)
|
||||
ON CONFLICT (track_id, seq) DO NOTHING;
|
||||
INSERT INTO track_waypoints (track_id, seq, x, y, heading_rad, speed_ms, curvature)
|
||||
VALUES ('barcelona-catalunya', 3, 1.5, 0.95, 3.141592653589793, 2, 2)
|
||||
ON CONFLICT (track_id, seq) DO NOTHING;
|
||||
INSERT INTO track_waypoints (track_id, seq, x, y, heading_rad, speed_ms, curvature)
|
||||
VALUES ('barcelona-catalunya', 4, 1.2, 1.1, 3.4415926535897934, 2.6, 1)
|
||||
ON CONFLICT (track_id, seq) DO NOTHING;
|
||||
INSERT INTO track_waypoints (track_id, seq, x, y, heading_rad, speed_ms, curvature)
|
||||
VALUES ('barcelona-catalunya', 5, 0.95, 1, 4.0415926535897935, 2.6, 1)
|
||||
ON CONFLICT (track_id, seq) DO NOTHING;
|
||||
INSERT INTO track_waypoints (track_id, seq, x, y, heading_rad, speed_ms, curvature)
|
||||
VALUES ('barcelona-catalunya', 6, 0.8, 1.2, -1.5707963267948966, 2.4, 1.2)
|
||||
ON CONFLICT (track_id, seq) DO NOTHING;
|
||||
INSERT INTO track_waypoints (track_id, seq, x, y, heading_rad, speed_ms, curvature)
|
||||
VALUES ('barcelona-catalunya', 7, 1.05, 1.5, 0, 3.2, 0.7)
|
||||
ON CONFLICT (track_id, seq) DO NOTHING;
|
||||
INSERT INTO track_waypoints (track_id, seq, x, y, heading_rad, speed_ms, curvature)
|
||||
VALUES ('barcelona-catalunya', 8, 1.3, 1.65, 1.5707963267948966, 2.4, 1)
|
||||
ON CONFLICT (track_id, seq) DO NOTHING;
|
||||
INSERT INTO track_waypoints (track_id, seq, x, y, heading_rad, speed_ms, curvature)
|
||||
VALUES ('barcelona-catalunya', 9, 1.15, 1.85, 3.141592653589793, 2.4, 1)
|
||||
ON CONFLICT (track_id, seq) DO NOTHING;
|
||||
INSERT INTO track_waypoints (track_id, seq, x, y, heading_rad, speed_ms, curvature)
|
||||
VALUES ('barcelona-catalunya', 10, 1.4, 2, 2.641592653589793, 3, 0.7)
|
||||
ON CONFLICT (track_id, seq) DO NOTHING;
|
||||
INSERT INTO track_waypoints (track_id, seq, x, y, heading_rad, speed_ms, curvature)
|
||||
VALUES ('barcelona-catalunya', 11, 1.7, 2, 2.141592653589793, 3, 0.7)
|
||||
ON CONFLICT (track_id, seq) DO NOTHING;
|
||||
INSERT INTO track_waypoints (track_id, seq, x, y, heading_rad, speed_ms, curvature)
|
||||
VALUES ('barcelona-catalunya', 12, 1.95, 2.2, 1.5707963267948966, 2.8, 0.5)
|
||||
ON CONFLICT (track_id, seq) DO NOTHING;
|
||||
INSERT INTO track_waypoints (track_id, seq, x, y, heading_rad, speed_ms, curvature)
|
||||
VALUES ('barcelona-catalunya', 13, 1.65, 2.5, 0.3, 2.8, 0.5)
|
||||
ON CONFLICT (track_id, seq) DO NOTHING;
|
||||
INSERT INTO track_waypoints (track_id, seq, x, y, heading_rad, speed_ms, curvature)
|
||||
VALUES ('barcelona-catalunya', 14, 2.2, 2.7, 0.7, 3.2, 0.5)
|
||||
ON CONFLICT (track_id, seq) DO NOTHING;
|
||||
INSERT INTO track_waypoints (track_id, seq, x, y, heading_rad, speed_ms, curvature)
|
||||
VALUES ('barcelona-catalunya', 15, 2.8, 2.7, 1.1, 3.4, 0.5)
|
||||
ON CONFLICT (track_id, seq) DO NOTHING;
|
||||
INSERT INTO track_waypoints (track_id, seq, x, y, heading_rad, speed_ms, curvature)
|
||||
VALUES ('barcelona-catalunya', 16, 3.1, 2.5, 1.9707963267948967, 2.2, 1.4)
|
||||
ON CONFLICT (track_id, seq) DO NOTHING;
|
||||
INSERT INTO track_waypoints (track_id, seq, x, y, heading_rad, speed_ms, curvature)
|
||||
VALUES ('barcelona-catalunya', 17, 2.95, 2.2, 3.541592653589793, 2.2, 1.4)
|
||||
ON CONFLICT (track_id, seq) DO NOTHING;
|
||||
INSERT INTO track_waypoints (track_id, seq, x, y, heading_rad, speed_ms, curvature)
|
||||
VALUES ('barcelona-catalunya', 18, 3.3, 1.9, 0, 4, 0)
|
||||
ON CONFLICT (track_id, seq) DO NOTHING;
|
||||
INSERT INTO track_waypoints (track_id, seq, x, y, heading_rad, speed_ms, curvature)
|
||||
VALUES ('barcelona-catalunya', 19, 4, 1.9, 0, 4, 0)
|
||||
ON CONFLICT (track_id, seq) DO NOTHING;
|
||||
INSERT INTO track_waypoints (track_id, seq, x, y, heading_rad, speed_ms, curvature)
|
||||
VALUES ('barcelona-catalunya', 20, 4.05, 1.6, -1.5707963267948966, 2.4, 1.4)
|
||||
ON CONFLICT (track_id, seq) DO NOTHING;
|
||||
INSERT INTO track_waypoints (track_id, seq, x, y, heading_rad, speed_ms, curvature)
|
||||
VALUES ('barcelona-catalunya', 21, 3.8, 1.4, 3.141592653589793, 2.4, 1.4)
|
||||
ON CONFLICT (track_id, seq) DO NOTHING;
|
||||
INSERT INTO track_waypoints (track_id, seq, x, y, heading_rad, speed_ms, curvature)
|
||||
VALUES ('barcelona-catalunya', 22, 3.5, 1.5, 3.9269908169872414, 2.6, 1)
|
||||
ON CONFLICT (track_id, seq) DO NOTHING;
|
||||
INSERT INTO track_waypoints (track_id, seq, x, y, heading_rad, speed_ms, curvature)
|
||||
VALUES ('barcelona-catalunya', 23, 3.1, 1.25, -1.9707963267948967, 3, 0.7)
|
||||
ON CONFLICT (track_id, seq) DO NOTHING;
|
||||
INSERT INTO track_waypoints (track_id, seq, x, y, heading_rad, speed_ms, curvature)
|
||||
VALUES ('barcelona-catalunya', 24, 2.7, 1, -2.4707963267948965, 3, 0.7)
|
||||
ON CONFLICT (track_id, seq) DO NOTHING;
|
||||
INSERT INTO track_waypoints (track_id, seq, x, y, heading_rad, speed_ms, curvature)
|
||||
VALUES ('barcelona-catalunya', 25, 2.3, 0.7, 3.541592653589793, 3.4, 0.5)
|
||||
ON CONFLICT (track_id, seq) DO NOTHING;
|
||||
INSERT INTO track_waypoints (track_id, seq, x, y, heading_rad, speed_ms, curvature)
|
||||
VALUES ('barcelona-catalunya', 26, 1.6, 0.5, 3.3415926535897933, 3.6, 0.4)
|
||||
ON CONFLICT (track_id, seq) DO NOTHING;
|
||||
INSERT INTO track_waypoints (track_id, seq, x, y, heading_rad, speed_ms, curvature)
|
||||
VALUES ('barcelona-catalunya', 27, 0.9, 0.42, 0, 4, 0)
|
||||
ON CONFLICT (track_id, seq) DO NOTHING;
|
||||
|
||||
INSERT INTO track_tags (track_id, tag) VALUES ('barcelona-catalunya', 'f1')
|
||||
ON CONFLICT DO NOTHING;
|
||||
INSERT INTO track_tags (track_id, tag) VALUES ('barcelona-catalunya', 'balanced')
|
||||
ON CONFLICT DO NOTHING;
|
||||
INSERT INTO track_tags (track_id, tag) VALUES ('barcelona-catalunya', 'testing')
|
||||
ON CONFLICT DO NOTHING;
|
||||
INSERT INTO track_tags (track_id, tag) VALUES ('barcelona-catalunya', 'barcelona')
|
||||
ON CONFLICT DO NOTHING;
|
||||
|
||||
INSERT INTO tracks (id, name, description, author_id, visibility, scale,
|
||||
length_m, width_m, lane_width_m, surface, best_lap_ms, best_lap_holder,
|
||||
bounds_min_x, bounds_min_y, bounds_max_x, bounds_max_y,
|
||||
created_ms, updated_ms)
|
||||
VALUES ('austria-redbull-ring', 'Austria (Red Bull Ring)', 'Red Bull Ring. Short, fast, three straights separated by hairpins.', 'system', 'system', 27,
|
||||
3.5500000000000003, 2, 0.18, 'wood', 0, 'Verstappen',
|
||||
0.3, 0.4, 3.85, 2.4,
|
||||
1700000000000, 1700000000000)
|
||||
ON CONFLICT (id) DO NOTHING;
|
||||
|
||||
INSERT INTO track_waypoints (track_id, seq, x, y, heading_rad, speed_ms, curvature)
|
||||
VALUES ('austria-redbull-ring', 0, 0.3, 0.4, 0, 4.8, 0)
|
||||
ON CONFLICT (track_id, seq) DO NOTHING;
|
||||
INSERT INTO track_waypoints (track_id, seq, x, y, heading_rad, speed_ms, curvature)
|
||||
VALUES ('austria-redbull-ring', 1, 1.6, 0.4, 0, 4.8, 0)
|
||||
ON CONFLICT (track_id, seq) DO NOTHING;
|
||||
INSERT INTO track_waypoints (track_id, seq, x, y, heading_rad, speed_ms, curvature)
|
||||
VALUES ('austria-redbull-ring', 2, 1.85, 0.65, 1.5707963267948966, 2, 1.8)
|
||||
ON CONFLICT (track_id, seq) DO NOTHING;
|
||||
INSERT INTO track_waypoints (track_id, seq, x, y, heading_rad, speed_ms, curvature)
|
||||
VALUES ('austria-redbull-ring', 3, 1.6, 0.95, 3.141592653589793, 2, 1.8)
|
||||
ON CONFLICT (track_id, seq) DO NOTHING;
|
||||
INSERT INTO track_waypoints (track_id, seq, x, y, heading_rad, speed_ms, curvature)
|
||||
VALUES ('austria-redbull-ring', 4, 1.3, 1, 3.641592653589793, 3, 0.7)
|
||||
ON CONFLICT (track_id, seq) DO NOTHING;
|
||||
INSERT INTO track_waypoints (track_id, seq, x, y, heading_rad, speed_ms, curvature)
|
||||
VALUES ('austria-redbull-ring', 5, 1.05, 1.2, -1.5707963267948966, 2.6, 1)
|
||||
ON CONFLICT (track_id, seq) DO NOTHING;
|
||||
INSERT INTO track_waypoints (track_id, seq, x, y, heading_rad, speed_ms, curvature)
|
||||
VALUES ('austria-redbull-ring', 6, 1.4, 1.4, 0, 3.2, 0.5)
|
||||
ON CONFLICT (track_id, seq) DO NOTHING;
|
||||
INSERT INTO track_waypoints (track_id, seq, x, y, heading_rad, speed_ms, curvature)
|
||||
VALUES ('austria-redbull-ring', 7, 1.85, 1.4, 1.7707963267948965, 3.2, 0.5)
|
||||
ON CONFLICT (track_id, seq) DO NOTHING;
|
||||
INSERT INTO track_waypoints (track_id, seq, x, y, heading_rad, speed_ms, curvature)
|
||||
VALUES ('austria-redbull-ring', 8, 2.1, 1.65, 3.141592653589793, 3, 0.7)
|
||||
ON CONFLICT (track_id, seq) DO NOTHING;
|
||||
INSERT INTO track_waypoints (track_id, seq, x, y, heading_rad, speed_ms, curvature)
|
||||
VALUES ('austria-redbull-ring', 9, 2, 1.85, -1.5707963267948966, 3, 0.7)
|
||||
ON CONFLICT (track_id, seq) DO NOTHING;
|
||||
INSERT INTO track_waypoints (track_id, seq, x, y, heading_rad, speed_ms, curvature)
|
||||
VALUES ('austria-redbull-ring', 10, 2.25, 2.05, 0, 2, 1.8)
|
||||
ON CONFLICT (track_id, seq) DO NOTHING;
|
||||
INSERT INTO track_waypoints (track_id, seq, x, y, heading_rad, speed_ms, curvature)
|
||||
VALUES ('austria-redbull-ring', 11, 2.4, 2, 1.5707963267948966, 2, 1.8)
|
||||
ON CONFLICT (track_id, seq) DO NOTHING;
|
||||
INSERT INTO track_waypoints (track_id, seq, x, y, heading_rad, speed_ms, curvature)
|
||||
VALUES ('austria-redbull-ring', 12, 2.4, 2.2, 3.141592653589793, 2, 1.8)
|
||||
ON CONFLICT (track_id, seq) DO NOTHING;
|
||||
INSERT INTO track_waypoints (track_id, seq, x, y, heading_rad, speed_ms, curvature)
|
||||
VALUES ('austria-redbull-ring', 13, 2.2, 2.3, -1.5707963267948966, 2, 1.8)
|
||||
ON CONFLICT (track_id, seq) DO NOTHING;
|
||||
INSERT INTO track_waypoints (track_id, seq, x, y, heading_rad, speed_ms, curvature)
|
||||
VALUES ('austria-redbull-ring', 14, 2.55, 2.4, -0.2, 3.4, 0.4)
|
||||
ON CONFLICT (track_id, seq) DO NOTHING;
|
||||
INSERT INTO track_waypoints (track_id, seq, x, y, heading_rad, speed_ms, curvature)
|
||||
VALUES ('austria-redbull-ring', 15, 3, 2.4, 0, 4, 0)
|
||||
ON CONFLICT (track_id, seq) DO NOTHING;
|
||||
INSERT INTO track_waypoints (track_id, seq, x, y, heading_rad, speed_ms, curvature)
|
||||
VALUES ('austria-redbull-ring', 16, 3.5, 2.4, 0, 4.5, 0)
|
||||
ON CONFLICT (track_id, seq) DO NOTHING;
|
||||
INSERT INTO track_waypoints (track_id, seq, x, y, heading_rad, speed_ms, curvature)
|
||||
VALUES ('austria-redbull-ring', 17, 3.85, 2.15, 1.7707963267948965, 3.4, 0.6)
|
||||
ON CONFLICT (track_id, seq) DO NOTHING;
|
||||
INSERT INTO track_waypoints (track_id, seq, x, y, heading_rad, speed_ms, curvature)
|
||||
VALUES ('austria-redbull-ring', 18, 3.6, 1.8, 3.141592653589793, 3, 0.8)
|
||||
ON CONFLICT (track_id, seq) DO NOTHING;
|
||||
INSERT INTO track_waypoints (track_id, seq, x, y, heading_rad, speed_ms, curvature)
|
||||
VALUES ('austria-redbull-ring', 19, 3.25, 1.85, 3.741592653589793, 3, 0.8)
|
||||
ON CONFLICT (track_id, seq) DO NOTHING;
|
||||
INSERT INTO track_waypoints (track_id, seq, x, y, heading_rad, speed_ms, curvature)
|
||||
VALUES ('austria-redbull-ring', 20, 3, 1.6, -1.9707963267948967, 3.2, 0.6)
|
||||
ON CONFLICT (track_id, seq) DO NOTHING;
|
||||
INSERT INTO track_waypoints (track_id, seq, x, y, heading_rad, speed_ms, curvature)
|
||||
VALUES ('austria-redbull-ring', 21, 2.6, 1.4, -3.141592653589793, 3.4, 0.5)
|
||||
ON CONFLICT (track_id, seq) DO NOTHING;
|
||||
INSERT INTO track_waypoints (track_id, seq, x, y, heading_rad, speed_ms, curvature)
|
||||
VALUES ('austria-redbull-ring', 22, 2, 1.2, 2.641592653589793, 3.6, 0.4)
|
||||
ON CONFLICT (track_id, seq) DO NOTHING;
|
||||
INSERT INTO track_waypoints (track_id, seq, x, y, heading_rad, speed_ms, curvature)
|
||||
VALUES ('austria-redbull-ring', 23, 1.4, 0.8, 2.9415926535897934, 3.8, 0.3)
|
||||
ON CONFLICT (track_id, seq) DO NOTHING;
|
||||
INSERT INTO track_waypoints (track_id, seq, x, y, heading_rad, speed_ms, curvature)
|
||||
VALUES ('austria-redbull-ring', 24, 0.8, 0.5, 0, 4.2, 0.2)
|
||||
ON CONFLICT (track_id, seq) DO NOTHING;
|
||||
|
||||
INSERT INTO track_tags (track_id, tag) VALUES ('austria-redbull-ring', 'f1')
|
||||
ON CONFLICT DO NOTHING;
|
||||
INSERT INTO track_tags (track_id, tag) VALUES ('austria-redbull-ring', 'short')
|
||||
ON CONFLICT DO NOTHING;
|
||||
INSERT INTO track_tags (track_id, tag) VALUES ('austria-redbull-ring', 'fast')
|
||||
ON CONFLICT DO NOTHING;
|
||||
INSERT INTO track_tags (track_id, tag) VALUES ('austria-redbull-ring', 'austria')
|
||||
ON CONFLICT DO NOTHING;
|
||||
|
||||
INSERT INTO tracks (id, name, description, author_id, visibility, scale,
|
||||
length_m, width_m, lane_width_m, surface, best_lap_ms, best_lap_holder,
|
||||
bounds_min_x, bounds_min_y, bounds_max_x, bounds_max_y,
|
||||
created_ms, updated_ms)
|
||||
VALUES ('great-britain-silverstone', 'Great Britain (Silverstone)', 'Silverstone Circuit. Fast, flowing corners; home of British motorsport.', 'system', 'system', 27,
|
||||
3.5500000000000003, 1.2499999999999998, 0.18, 'carpet', 0, 'Hamilton',
|
||||
0.3, 1.8, 3.85, 3.05,
|
||||
1700000000000, 1700000000000)
|
||||
ON CONFLICT (id) DO NOTHING;
|
||||
|
||||
INSERT INTO track_waypoints (track_id, seq, x, y, heading_rad, speed_ms, curvature)
|
||||
VALUES ('great-britain-silverstone', 0, 0.3, 2.8, 0, 5, 0)
|
||||
ON CONFLICT (track_id, seq) DO NOTHING;
|
||||
INSERT INTO track_waypoints (track_id, seq, x, y, heading_rad, speed_ms, curvature)
|
||||
VALUES ('great-britain-silverstone', 1, 2.4, 2.8, 0, 5, 0)
|
||||
ON CONFLICT (track_id, seq) DO NOTHING;
|
||||
INSERT INTO track_waypoints (track_id, seq, x, y, heading_rad, speed_ms, curvature)
|
||||
VALUES ('great-britain-silverstone', 2, 2.8, 2.65, -1.5707963267948966, 3, 0.8)
|
||||
ON CONFLICT (track_id, seq) DO NOTHING;
|
||||
INSERT INTO track_waypoints (track_id, seq, x, y, heading_rad, speed_ms, curvature)
|
||||
VALUES ('great-britain-silverstone', 3, 2.6, 2.3, -3.141592653589793, 3.4, 0.6)
|
||||
ON CONFLICT (track_id, seq) DO NOTHING;
|
||||
INSERT INTO track_waypoints (track_id, seq, x, y, heading_rad, speed_ms, curvature)
|
||||
VALUES ('great-britain-silverstone', 4, 2.95, 2.05, -2.0707963267948966, 3.2, 0.7)
|
||||
ON CONFLICT (track_id, seq) DO NOTHING;
|
||||
INSERT INTO track_waypoints (track_id, seq, x, y, heading_rad, speed_ms, curvature)
|
||||
VALUES ('great-britain-silverstone', 5, 3.3, 1.8, 0, 2.2, 1.6)
|
||||
ON CONFLICT (track_id, seq) DO NOTHING;
|
||||
INSERT INTO track_waypoints (track_id, seq, x, y, heading_rad, speed_ms, curvature)
|
||||
VALUES ('great-britain-silverstone', 6, 3.6, 1.95, 1.5707963267948966, 2.2, 1.6)
|
||||
ON CONFLICT (track_id, seq) DO NOTHING;
|
||||
INSERT INTO track_waypoints (track_id, seq, x, y, heading_rad, speed_ms, curvature)
|
||||
VALUES ('great-britain-silverstone', 7, 3.6, 2.3, 3.141592653589793, 3, 0.7)
|
||||
ON CONFLICT (track_id, seq) DO NOTHING;
|
||||
INSERT INTO track_waypoints (track_id, seq, x, y, heading_rad, speed_ms, curvature)
|
||||
VALUES ('great-britain-silverstone', 8, 3.85, 2.55, 1.5707963267948966, 2.6, 1)
|
||||
ON CONFLICT (track_id, seq) DO NOTHING;
|
||||
INSERT INTO track_waypoints (track_id, seq, x, y, heading_rad, speed_ms, curvature)
|
||||
VALUES ('great-britain-silverstone', 9, 3.55, 2.85, 0, 2.4, 1)
|
||||
ON CONFLICT (track_id, seq) DO NOTHING;
|
||||
INSERT INTO track_waypoints (track_id, seq, x, y, heading_rad, speed_ms, curvature)
|
||||
VALUES ('great-britain-silverstone', 10, 3.25, 2.85, 1.5707963267948966, 2.4, 1)
|
||||
ON CONFLICT (track_id, seq) DO NOTHING;
|
||||
INSERT INTO track_waypoints (track_id, seq, x, y, heading_rad, speed_ms, curvature)
|
||||
VALUES ('great-britain-silverstone', 11, 3.05, 2.55, -1.8707963267948966, 3.4, 0.5)
|
||||
ON CONFLICT (track_id, seq) DO NOTHING;
|
||||
INSERT INTO track_waypoints (track_id, seq, x, y, heading_rad, speed_ms, curvature)
|
||||
VALUES ('great-britain-silverstone', 12, 2.85, 2.65, -3.141592653589793, 4, 0.3)
|
||||
ON CONFLICT (track_id, seq) DO NOTHING;
|
||||
INSERT INTO track_waypoints (track_id, seq, x, y, heading_rad, speed_ms, curvature)
|
||||
VALUES ('great-britain-silverstone', 13, 1.8, 2.8, 0, 4.6, 0)
|
||||
ON CONFLICT (track_id, seq) DO NOTHING;
|
||||
INSERT INTO track_waypoints (track_id, seq, x, y, heading_rad, speed_ms, curvature)
|
||||
VALUES ('great-britain-silverstone', 14, 1.2, 2.95, 1.7707963267948965, 3.8, 0.4)
|
||||
ON CONFLICT (track_id, seq) DO NOTHING;
|
||||
INSERT INTO track_waypoints (track_id, seq, x, y, heading_rad, speed_ms, curvature)
|
||||
VALUES ('great-britain-silverstone', 15, 1, 2.65, 3.541592653589793, 3.6, 0.5)
|
||||
ON CONFLICT (track_id, seq) DO NOTHING;
|
||||
INSERT INTO track_waypoints (track_id, seq, x, y, heading_rad, speed_ms, curvature)
|
||||
VALUES ('great-britain-silverstone', 16, 0.7, 2.4, -1.8707963267948966, 2.4, 1.2)
|
||||
ON CONFLICT (track_id, seq) DO NOTHING;
|
||||
INSERT INTO track_waypoints (track_id, seq, x, y, heading_rad, speed_ms, curvature)
|
||||
VALUES ('great-britain-silverstone', 17, 0.5, 2.6, 0, 2.6, 0.9)
|
||||
ON CONFLICT (track_id, seq) DO NOTHING;
|
||||
INSERT INTO track_waypoints (track_id, seq, x, y, heading_rad, speed_ms, curvature)
|
||||
VALUES ('great-britain-silverstone', 18, 0.7, 2.85, 1.5707963267948966, 3, 0.7)
|
||||
ON CONFLICT (track_id, seq) DO NOTHING;
|
||||
INSERT INTO track_waypoints (track_id, seq, x, y, heading_rad, speed_ms, curvature)
|
||||
VALUES ('great-britain-silverstone', 19, 0.45, 3.05, 3.541592653589793, 2.6, 1)
|
||||
ON CONFLICT (track_id, seq) DO NOTHING;
|
||||
INSERT INTO track_waypoints (track_id, seq, x, y, heading_rad, speed_ms, curvature)
|
||||
VALUES ('great-britain-silverstone', 20, 0.7, 2.5, -1.1707963267948966, 2.4, 1)
|
||||
ON CONFLICT (track_id, seq) DO NOTHING;
|
||||
INSERT INTO track_waypoints (track_id, seq, x, y, heading_rad, speed_ms, curvature)
|
||||
VALUES ('great-britain-silverstone', 21, 0.5, 2.05, 3.541592653589793, 2.6, 0.8)
|
||||
ON CONFLICT (track_id, seq) DO NOTHING;
|
||||
INSERT INTO track_waypoints (track_id, seq, x, y, heading_rad, speed_ms, curvature)
|
||||
VALUES ('great-britain-silverstone', 22, 0.3, 2.4, 1.5707963267948966, 2.4, 1)
|
||||
ON CONFLICT (track_id, seq) DO NOTHING;
|
||||
|
||||
INSERT INTO track_tags (track_id, tag) VALUES ('great-britain-silverstone', 'f1')
|
||||
ON CONFLICT DO NOTHING;
|
||||
INSERT INTO track_tags (track_id, tag) VALUES ('great-britain-silverstone', 'fast')
|
||||
ON CONFLICT DO NOTHING;
|
||||
INSERT INTO track_tags (track_id, tag) VALUES ('great-britain-silverstone', 'flowing')
|
||||
ON CONFLICT DO NOTHING;
|
||||
INSERT INTO track_tags (track_id, tag) VALUES ('great-britain-silverstone', 'silverstone')
|
||||
ON CONFLICT DO NOTHING;
|
||||
|
||||
INSERT INTO tracks (id, name, description, author_id, visibility, scale,
|
||||
length_m, width_m, lane_width_m, surface, best_lap_ms, best_lap_holder,
|
||||
bounds_min_x, bounds_min_y, bounds_max_x, bounds_max_y,
|
||||
created_ms, updated_ms)
|
||||
VALUES ('belgium-spa', 'Belgium (Spa-Francorchamps)', 'Spa-Francorchamps. Long, fast, legendary Eau Rouge / Raidillon.', 'system', 'system', 27,
|
||||
3.85, 2.25, 0.18, 'carpet', 0, 'Verstappen',
|
||||
0.4, 0.5, 4.25, 2.75,
|
||||
1700000000000, 1700000000000)
|
||||
ON CONFLICT (id) DO NOTHING;
|
||||
|
||||
INSERT INTO track_waypoints (track_id, seq, x, y, heading_rad, speed_ms, curvature)
|
||||
VALUES ('belgium-spa', 0, 0.4, 0.5, 0, 4.8, 0)
|
||||
ON CONFLICT (track_id, seq) DO NOTHING;
|
||||
INSERT INTO track_waypoints (track_id, seq, x, y, heading_rad, speed_ms, curvature)
|
||||
VALUES ('belgium-spa', 1, 1.6, 0.5, 0, 4.8, 0)
|
||||
ON CONFLICT (track_id, seq) DO NOTHING;
|
||||
INSERT INTO track_waypoints (track_id, seq, x, y, heading_rad, speed_ms, curvature)
|
||||
VALUES ('belgium-spa', 2, 1.95, 0.6, 0.3, 4.2, 0.5)
|
||||
ON CONFLICT (track_id, seq) DO NOTHING;
|
||||
INSERT INTO track_waypoints (track_id, seq, x, y, heading_rad, speed_ms, curvature)
|
||||
VALUES ('belgium-spa', 3, 2.2, 0.95, 0.9, 4, 0.6)
|
||||
ON CONFLICT (track_id, seq) DO NOTHING;
|
||||
INSERT INTO track_waypoints (track_id, seq, x, y, heading_rad, speed_ms, curvature)
|
||||
VALUES ('belgium-spa', 4, 2.1, 1.3, 3.541592653589793, 4, 0.6)
|
||||
ON CONFLICT (track_id, seq) DO NOTHING;
|
||||
INSERT INTO track_waypoints (track_id, seq, x, y, heading_rad, speed_ms, curvature)
|
||||
VALUES ('belgium-spa', 5, 2.7, 1.5, 0, 5, 0)
|
||||
ON CONFLICT (track_id, seq) DO NOTHING;
|
||||
INSERT INTO track_waypoints (track_id, seq, x, y, heading_rad, speed_ms, curvature)
|
||||
VALUES ('belgium-spa', 6, 3.5, 1.5, 0, 5, 0)
|
||||
ON CONFLICT (track_id, seq) DO NOTHING;
|
||||
INSERT INTO track_waypoints (track_id, seq, x, y, heading_rad, speed_ms, curvature)
|
||||
VALUES ('belgium-spa', 7, 3.85, 1.3, -1.5707963267948966, 2.4, 1.4)
|
||||
ON CONFLICT (track_id, seq) DO NOTHING;
|
||||
INSERT INTO track_waypoints (track_id, seq, x, y, heading_rad, speed_ms, curvature)
|
||||
VALUES ('belgium-spa', 8, 3.6, 1.1, 3.4415926535897934, 2.6, 1.2)
|
||||
ON CONFLICT (track_id, seq) DO NOTHING;
|
||||
INSERT INTO track_waypoints (track_id, seq, x, y, heading_rad, speed_ms, curvature)
|
||||
VALUES ('belgium-spa', 9, 3.3, 1.25, 4.0415926535897935, 2.6, 1.2)
|
||||
ON CONFLICT (track_id, seq) DO NOTHING;
|
||||
INSERT INTO track_waypoints (track_id, seq, x, y, heading_rad, speed_ms, curvature)
|
||||
VALUES ('belgium-spa', 10, 3.5, 1.55, 1.5707963267948966, 3.6, 0.4)
|
||||
ON CONFLICT (track_id, seq) DO NOTHING;
|
||||
INSERT INTO track_waypoints (track_id, seq, x, y, heading_rad, speed_ms, curvature)
|
||||
VALUES ('belgium-spa', 11, 3.25, 1.85, 0, 2.2, 1.6)
|
||||
ON CONFLICT (track_id, seq) DO NOTHING;
|
||||
INSERT INTO track_waypoints (track_id, seq, x, y, heading_rad, speed_ms, curvature)
|
||||
VALUES ('belgium-spa', 12, 3.05, 1.7, -1.5707963267948966, 2.4, 1.4)
|
||||
ON CONFLICT (track_id, seq) DO NOTHING;
|
||||
INSERT INTO track_waypoints (track_id, seq, x, y, heading_rad, speed_ms, curvature)
|
||||
VALUES ('belgium-spa', 13, 3.25, 1.5, 0, 3, 0.7)
|
||||
ON CONFLICT (track_id, seq) DO NOTHING;
|
||||
INSERT INTO track_waypoints (track_id, seq, x, y, heading_rad, speed_ms, curvature)
|
||||
VALUES ('belgium-spa', 14, 3.7, 1.65, 1.8707963267948966, 3.4, 0.5)
|
||||
ON CONFLICT (track_id, seq) DO NOTHING;
|
||||
INSERT INTO track_waypoints (track_id, seq, x, y, heading_rad, speed_ms, curvature)
|
||||
VALUES ('belgium-spa', 15, 4.1, 2, 2.1707963267948966, 4, 0.3)
|
||||
ON CONFLICT (track_id, seq) DO NOTHING;
|
||||
INSERT INTO track_waypoints (track_id, seq, x, y, heading_rad, speed_ms, curvature)
|
||||
VALUES ('belgium-spa', 16, 4.25, 2.4, 3.541592653589793, 4.6, 0.3)
|
||||
ON CONFLICT (track_id, seq) DO NOTHING;
|
||||
INSERT INTO track_waypoints (track_id, seq, x, y, heading_rad, speed_ms, curvature)
|
||||
VALUES ('belgium-spa', 17, 4, 2.7, -1.8707963267948966, 2.4, 1.4)
|
||||
ON CONFLICT (track_id, seq) DO NOTHING;
|
||||
INSERT INTO track_waypoints (track_id, seq, x, y, heading_rad, speed_ms, curvature)
|
||||
VALUES ('belgium-spa', 18, 3.7, 2.55, 3.141592653589793, 2.4, 1.4)
|
||||
ON CONFLICT (track_id, seq) DO NOTHING;
|
||||
INSERT INTO track_waypoints (track_id, seq, x, y, heading_rad, speed_ms, curvature)
|
||||
VALUES ('belgium-spa', 19, 3.55, 2.75, 3.8415926535897933, 2.4, 1.4)
|
||||
ON CONFLICT (track_id, seq) DO NOTHING;
|
||||
INSERT INTO track_waypoints (track_id, seq, x, y, heading_rad, speed_ms, curvature)
|
||||
VALUES ('belgium-spa', 20, 3.05, 2.7, -1.5707963267948966, 2, 1.8)
|
||||
ON CONFLICT (track_id, seq) DO NOTHING;
|
||||
INSERT INTO track_waypoints (track_id, seq, x, y, heading_rad, speed_ms, curvature)
|
||||
VALUES ('belgium-spa', 21, 2.85, 2.45, 0, 2, 1.8)
|
||||
ON CONFLICT (track_id, seq) DO NOTHING;
|
||||
INSERT INTO track_waypoints (track_id, seq, x, y, heading_rad, speed_ms, curvature)
|
||||
VALUES ('belgium-spa', 22, 2, 2.2, 2.8415926535897933, 3.6, 0.3)
|
||||
ON CONFLICT (track_id, seq) DO NOTHING;
|
||||
INSERT INTO track_waypoints (track_id, seq, x, y, heading_rad, speed_ms, curvature)
|
||||
VALUES ('belgium-spa', 23, 1.2, 1.6, 2.541592653589793, 4, 0.2)
|
||||
ON CONFLICT (track_id, seq) DO NOTHING;
|
||||
INSERT INTO track_waypoints (track_id, seq, x, y, heading_rad, speed_ms, curvature)
|
||||
VALUES ('belgium-spa', 24, 0.6, 1.05, 2.8415926535897933, 4.4, 0.2)
|
||||
ON CONFLICT (track_id, seq) DO NOTHING;
|
||||
|
||||
INSERT INTO track_tags (track_id, tag) VALUES ('belgium-spa', 'f1')
|
||||
ON CONFLICT DO NOTHING;
|
||||
INSERT INTO track_tags (track_id, tag) VALUES ('belgium-spa', 'long')
|
||||
ON CONFLICT DO NOTHING;
|
||||
INSERT INTO track_tags (track_id, tag) VALUES ('belgium-spa', 'fast')
|
||||
ON CONFLICT DO NOTHING;
|
||||
INSERT INTO track_tags (track_id, tag) VALUES ('belgium-spa', 'spa')
|
||||
ON CONFLICT DO NOTHING;
|
||||
|
||||
INSERT INTO cars (id, name, owner_id, visibility, scale,
|
||||
length_mm, width_mm, height_mm, weight_g,
|
||||
chassis_model, chassis_material, chassis_printed, chassis_wheelbase_mm, chassis_track_mm,
|
||||
motor_kind, motor_class, motor_kv, motor_power_w,
|
||||
battery_voltage_v, battery_capacity_mah, battery_cells, battery_chemistry,
|
||||
drive, top_speed_ms, color_hex, avatar_url, active,
|
||||
created_ms, updated_ms)
|
||||
VALUES ('f1-2024-redbull-rb20', 'Oracle Red Bull Racing RB20', 'system', 'system', 24,
|
||||
238, 83, 40, 33,
|
||||
'RB20 carbon monocoque', 'carbon-fibre', FALSE, 150, 75,
|
||||
'turbo-hybrid', 'F1 PU', 0, 746000,
|
||||
0, 0, 0, 'li-ion MGU-K',
|
||||
'2WD', 95, '#1e3a8a', '', TRUE,
|
||||
1700000000000, 1700000000000)
|
||||
ON CONFLICT (id) DO NOTHING;
|
||||
|
||||
INSERT INTO cars (id, name, owner_id, visibility, scale,
|
||||
length_mm, width_mm, height_mm, weight_g,
|
||||
chassis_model, chassis_material, chassis_printed, chassis_wheelbase_mm, chassis_track_mm,
|
||||
motor_kind, motor_class, motor_kv, motor_power_w,
|
||||
battery_voltage_v, battery_capacity_mah, battery_cells, battery_chemistry,
|
||||
drive, top_speed_ms, color_hex, avatar_url, active,
|
||||
created_ms, updated_ms)
|
||||
VALUES ('f1-2024-ferrari-sf24', 'Scuderia Ferrari SF-24', 'system', 'system', 24,
|
||||
238, 83, 40, 33,
|
||||
'SF-24 carbon monocoque', 'carbon-fibre', FALSE, 150, 75,
|
||||
'turbo-hybrid', 'F1 PU 066/12', 0, 746000,
|
||||
0, 0, 0, 'li-ion MGU-K',
|
||||
'2WD', 94, '#dc2626', '', TRUE,
|
||||
1700000000000, 1700000000000)
|
||||
ON CONFLICT (id) DO NOTHING;
|
||||
|
||||
INSERT INTO cars (id, name, owner_id, visibility, scale,
|
||||
length_mm, width_mm, height_mm, weight_g,
|
||||
chassis_model, chassis_material, chassis_printed, chassis_wheelbase_mm, chassis_track_mm,
|
||||
motor_kind, motor_class, motor_kv, motor_power_w,
|
||||
battery_voltage_v, battery_capacity_mah, battery_cells, battery_chemistry,
|
||||
drive, top_speed_ms, color_hex, avatar_url, active,
|
||||
created_ms, updated_ms)
|
||||
VALUES ('f1-2024-mclaren-mcl38', 'McLaren MCL38', 'system', 'system', 24,
|
||||
238, 83, 40, 33,
|
||||
'MCL38 carbon monocoque', 'carbon-fibre', FALSE, 150, 75,
|
||||
'turbo-hybrid', 'F1 PU Mercedes-derived', 0, 746000,
|
||||
0, 0, 0, 'li-ion MGU-K',
|
||||
'2WD', 94, '#ea580c', '', TRUE,
|
||||
1700000000000, 1700000000000)
|
||||
ON CONFLICT (id) DO NOTHING;
|
||||
|
||||
INSERT INTO cars (id, name, owner_id, visibility, scale,
|
||||
length_mm, width_mm, height_mm, weight_g,
|
||||
chassis_model, chassis_material, chassis_printed, chassis_wheelbase_mm, chassis_track_mm,
|
||||
motor_kind, motor_class, motor_kv, motor_power_w,
|
||||
battery_voltage_v, battery_capacity_mah, battery_cells, battery_chemistry,
|
||||
drive, top_speed_ms, color_hex, avatar_url, active,
|
||||
created_ms, updated_ms)
|
||||
VALUES ('f1-2024-mercedes-w15', 'Mercedes-AMG W15', 'system', 'system', 24,
|
||||
238, 83, 40, 33,
|
||||
'W15 carbon monocoque', 'carbon-fibre', FALSE, 150, 75,
|
||||
'turbo-hybrid', 'F1 PU M15', 0, 746000,
|
||||
0, 0, 0, 'li-ion MGU-K',
|
||||
'2WD', 94, '#06b6d4', '', TRUE,
|
||||
1700000000000, 1700000000000)
|
||||
ON CONFLICT (id) DO NOTHING;
|
||||
|
||||
INSERT INTO cars (id, name, owner_id, visibility, scale,
|
||||
length_mm, width_mm, height_mm, weight_g,
|
||||
chassis_model, chassis_material, chassis_printed, chassis_wheelbase_mm, chassis_track_mm,
|
||||
motor_kind, motor_class, motor_kv, motor_power_w,
|
||||
battery_voltage_v, battery_capacity_mah, battery_cells, battery_chemistry,
|
||||
drive, top_speed_ms, color_hex, avatar_url, active,
|
||||
created_ms, updated_ms)
|
||||
VALUES ('f1-2024-astonmartin-amr24', 'Aston Martin Aramco AMR24', 'system', 'system', 24,
|
||||
238, 83, 40, 33,
|
||||
'AMR24 carbon monocoque', 'carbon-fibre', FALSE, 150, 75,
|
||||
'turbo-hybrid', 'F1 PU Mercedes-derived', 0, 746000,
|
||||
0, 0, 0, 'li-ion MGU-K',
|
||||
'2WD', 94, '#16a34a', '', TRUE,
|
||||
1700000000000, 1700000000000)
|
||||
ON CONFLICT (id) DO NOTHING;
|
||||
|
||||
@@ -0,0 +1,588 @@
|
||||
-- 003_f1_seed.sql — replace legacy PoC seed (oval, figure-8, sprint-straight
|
||||
-- and 1/27 toy cars) with the F1 2024 catalog (5 tracks + 5 cars).
|
||||
-- Idempotent: drops the old system rows before re-inserting.
|
||||
|
||||
DELETE FROM cars WHERE id IN ('compact-1-27-touring', 'compact-1-27-formula');
|
||||
DELETE FROM tracks WHERE id IN ('oval-classic', 'figure-eight', 'sprint-straight');
|
||||
-- 002_seed.sql — initial system catalog (tracks + cars).
|
||||
-- Generated from internal/catalog/seeddefs via scripts/genseed.
|
||||
-- Idempotent: safe to re-apply (ON CONFLICT DO NOTHING).
|
||||
|
||||
INSERT INTO tracks (id, name, description, author_id, visibility, scale,
|
||||
length_m, width_m, lane_width_m, surface, best_lap_ms, best_lap_holder,
|
||||
bounds_min_x, bounds_min_y, bounds_max_x, bounds_max_y,
|
||||
created_ms, updated_ms)
|
||||
VALUES ('monaco', 'Monaco', 'Circuit de Monaco. Narrow street circuit, tight hairpins, no room for error.', 'system', 'system', 27,
|
||||
3.5500000000000003, 1.1, 0.18, 'tile', 0, 'Verstappen',
|
||||
0.4, 1.4, 3.95, 2.5,
|
||||
1700000000000, 1700000000000)
|
||||
ON CONFLICT (id) DO NOTHING;
|
||||
|
||||
INSERT INTO track_waypoints (track_id, seq, x, y, heading_rad, speed_ms, curvature)
|
||||
VALUES ('monaco', 0, 0.4, 2.2, 0, 3.2, 0)
|
||||
ON CONFLICT (track_id, seq) DO NOTHING;
|
||||
INSERT INTO track_waypoints (track_id, seq, x, y, heading_rad, speed_ms, curvature)
|
||||
VALUES ('monaco', 1, 1.1, 2.2, 0, 3, 0)
|
||||
ON CONFLICT (track_id, seq) DO NOTHING;
|
||||
INSERT INTO track_waypoints (track_id, seq, x, y, heading_rad, speed_ms, curvature)
|
||||
VALUES ('monaco', 2, 1.5, 2.05, -0.4, 2.4, 1.2)
|
||||
ON CONFLICT (track_id, seq) DO NOTHING;
|
||||
INSERT INTO track_waypoints (track_id, seq, x, y, heading_rad, speed_ms, curvature)
|
||||
VALUES ('monaco', 3, 1.7, 1.85, -0.9, 2.2, 1.8)
|
||||
ON CONFLICT (track_id, seq) DO NOTHING;
|
||||
INSERT INTO track_waypoints (track_id, seq, x, y, heading_rad, speed_ms, curvature)
|
||||
VALUES ('monaco', 4, 1.55, 1.55, -1.6, 2, 1.4)
|
||||
ON CONFLICT (track_id, seq) DO NOTHING;
|
||||
INSERT INTO track_waypoints (track_id, seq, x, y, heading_rad, speed_ms, curvature)
|
||||
VALUES ('monaco', 5, 1.25, 1.4, -2.4, 2.1, 1.2)
|
||||
ON CONFLICT (track_id, seq) DO NOTHING;
|
||||
INSERT INTO track_waypoints (track_id, seq, x, y, heading_rad, speed_ms, curvature)
|
||||
VALUES ('monaco', 6, 0.95, 1.55, 3.141592653589793, 1.9, 1.6)
|
||||
ON CONFLICT (track_id, seq) DO NOTHING;
|
||||
INSERT INTO track_waypoints (track_id, seq, x, y, heading_rad, speed_ms, curvature)
|
||||
VALUES ('monaco', 7, 0.75, 1.85, 2, 1.8, 2.2)
|
||||
ON CONFLICT (track_id, seq) DO NOTHING;
|
||||
INSERT INTO track_waypoints (track_id, seq, x, y, heading_rad, speed_ms, curvature)
|
||||
VALUES ('monaco', 8, 0.95, 2.15, 2.6, 1.8, 2.6)
|
||||
ON CONFLICT (track_id, seq) DO NOTHING;
|
||||
INSERT INTO track_waypoints (track_id, seq, x, y, heading_rad, speed_ms, curvature)
|
||||
VALUES ('monaco', 9, 1.2, 2.4, -2.8, 2.1, 1.4)
|
||||
ON CONFLICT (track_id, seq) DO NOTHING;
|
||||
INSERT INTO track_waypoints (track_id, seq, x, y, heading_rad, speed_ms, curvature)
|
||||
VALUES ('monaco', 10, 1.6, 2.5, -3, 2.4, 1)
|
||||
ON CONFLICT (track_id, seq) DO NOTHING;
|
||||
INSERT INTO track_waypoints (track_id, seq, x, y, heading_rad, speed_ms, curvature)
|
||||
VALUES ('monaco', 11, 2.6, 2.5, 0, 3.2, 0)
|
||||
ON CONFLICT (track_id, seq) DO NOTHING;
|
||||
INSERT INTO track_waypoints (track_id, seq, x, y, heading_rad, speed_ms, curvature)
|
||||
VALUES ('monaco', 12, 3.4, 2.5, 0, 3.2, 0)
|
||||
ON CONFLICT (track_id, seq) DO NOTHING;
|
||||
INSERT INTO track_waypoints (track_id, seq, x, y, heading_rad, speed_ms, curvature)
|
||||
VALUES ('monaco', 13, 3.6, 2.25, -0.5, 2.6, 1.5)
|
||||
ON CONFLICT (track_id, seq) DO NOTHING;
|
||||
INSERT INTO track_waypoints (track_id, seq, x, y, heading_rad, speed_ms, curvature)
|
||||
VALUES ('monaco', 14, 3.55, 1.95, 0.4, 2.6, 1.5)
|
||||
ON CONFLICT (track_id, seq) DO NOTHING;
|
||||
INSERT INTO track_waypoints (track_id, seq, x, y, heading_rad, speed_ms, curvature)
|
||||
VALUES ('monaco', 15, 3.3, 1.75, 1, 2.3, 1.4)
|
||||
ON CONFLICT (track_id, seq) DO NOTHING;
|
||||
INSERT INTO track_waypoints (track_id, seq, x, y, heading_rad, speed_ms, curvature)
|
||||
VALUES ('monaco', 16, 2.95, 1.55, 1.7, 2.1, 1.8)
|
||||
ON CONFLICT (track_id, seq) DO NOTHING;
|
||||
INSERT INTO track_waypoints (track_id, seq, x, y, heading_rad, speed_ms, curvature)
|
||||
VALUES ('monaco', 17, 2.6, 1.65, 2.6, 2.1, 1.8)
|
||||
ON CONFLICT (track_id, seq) DO NOTHING;
|
||||
INSERT INTO track_waypoints (track_id, seq, x, y, heading_rad, speed_ms, curvature)
|
||||
VALUES ('monaco', 18, 2.4, 1.9, -2.7, 2.3, 1.4)
|
||||
ON CONFLICT (track_id, seq) DO NOTHING;
|
||||
INSERT INTO track_waypoints (track_id, seq, x, y, heading_rad, speed_ms, curvature)
|
||||
VALUES ('monaco', 19, 2.4, 2.2, -3, 2.2, 1.6)
|
||||
ON CONFLICT (track_id, seq) DO NOTHING;
|
||||
INSERT INTO track_waypoints (track_id, seq, x, y, heading_rad, speed_ms, curvature)
|
||||
VALUES ('monaco', 20, 2.6, 2.4, 2.8, 2.5, 1)
|
||||
ON CONFLICT (track_id, seq) DO NOTHING;
|
||||
INSERT INTO track_waypoints (track_id, seq, x, y, heading_rad, speed_ms, curvature)
|
||||
VALUES ('monaco', 21, 3.2, 2.4, 0, 3.2, 0)
|
||||
ON CONFLICT (track_id, seq) DO NOTHING;
|
||||
INSERT INTO track_waypoints (track_id, seq, x, y, heading_rad, speed_ms, curvature)
|
||||
VALUES ('monaco', 22, 3.7, 2.4, 0, 3.2, 0)
|
||||
ON CONFLICT (track_id, seq) DO NOTHING;
|
||||
INSERT INTO track_waypoints (track_id, seq, x, y, heading_rad, speed_ms, curvature)
|
||||
VALUES ('monaco', 23, 3.95, 2.3, -0.3, 2.8, 0.8)
|
||||
ON CONFLICT (track_id, seq) DO NOTHING;
|
||||
|
||||
INSERT INTO track_tags (track_id, tag) VALUES ('monaco', 'f1')
|
||||
ON CONFLICT DO NOTHING;
|
||||
INSERT INTO track_tags (track_id, tag) VALUES ('monaco', 'street')
|
||||
ON CONFLICT DO NOTHING;
|
||||
INSERT INTO track_tags (track_id, tag) VALUES ('monaco', 'tight')
|
||||
ON CONFLICT DO NOTHING;
|
||||
INSERT INTO track_tags (track_id, tag) VALUES ('monaco', 'slow')
|
||||
ON CONFLICT DO NOTHING;
|
||||
INSERT INTO track_tags (track_id, tag) VALUES ('monaco', 'monaco')
|
||||
ON CONFLICT DO NOTHING;
|
||||
|
||||
INSERT INTO tracks (id, name, description, author_id, visibility, scale,
|
||||
length_m, width_m, lane_width_m, surface, best_lap_ms, best_lap_holder,
|
||||
bounds_min_x, bounds_min_y, bounds_max_x, bounds_max_y,
|
||||
created_ms, updated_ms)
|
||||
VALUES ('barcelona-catalunya', 'Barcelona-Catalunya', 'Circuit de Barcelona-Catalunya. Mix of high-speed corners and technical chicanes.', 'system', 'system', 27,
|
||||
3.75, 2.3000000000000003, 0.18, 'tile', 0, 'Verstappen',
|
||||
0.3, 0.4, 4.05, 2.7,
|
||||
1700000000000, 1700000000000)
|
||||
ON CONFLICT (id) DO NOTHING;
|
||||
|
||||
INSERT INTO track_waypoints (track_id, seq, x, y, heading_rad, speed_ms, curvature)
|
||||
VALUES ('barcelona-catalunya', 0, 0.3, 0.4, 0, 4.5, 0)
|
||||
ON CONFLICT (track_id, seq) DO NOTHING;
|
||||
INSERT INTO track_waypoints (track_id, seq, x, y, heading_rad, speed_ms, curvature)
|
||||
VALUES ('barcelona-catalunya', 1, 1.4, 0.4, 0, 4.5, 0)
|
||||
ON CONFLICT (track_id, seq) DO NOTHING;
|
||||
INSERT INTO track_waypoints (track_id, seq, x, y, heading_rad, speed_ms, curvature)
|
||||
VALUES ('barcelona-catalunya', 2, 1.7, 0.65, 1.5707963267948966, 2.2, 1.6)
|
||||
ON CONFLICT (track_id, seq) DO NOTHING;
|
||||
INSERT INTO track_waypoints (track_id, seq, x, y, heading_rad, speed_ms, curvature)
|
||||
VALUES ('barcelona-catalunya', 3, 1.5, 0.95, 3.141592653589793, 2, 2)
|
||||
ON CONFLICT (track_id, seq) DO NOTHING;
|
||||
INSERT INTO track_waypoints (track_id, seq, x, y, heading_rad, speed_ms, curvature)
|
||||
VALUES ('barcelona-catalunya', 4, 1.2, 1.1, 3.4415926535897934, 2.6, 1)
|
||||
ON CONFLICT (track_id, seq) DO NOTHING;
|
||||
INSERT INTO track_waypoints (track_id, seq, x, y, heading_rad, speed_ms, curvature)
|
||||
VALUES ('barcelona-catalunya', 5, 0.95, 1, 4.0415926535897935, 2.6, 1)
|
||||
ON CONFLICT (track_id, seq) DO NOTHING;
|
||||
INSERT INTO track_waypoints (track_id, seq, x, y, heading_rad, speed_ms, curvature)
|
||||
VALUES ('barcelona-catalunya', 6, 0.8, 1.2, -1.5707963267948966, 2.4, 1.2)
|
||||
ON CONFLICT (track_id, seq) DO NOTHING;
|
||||
INSERT INTO track_waypoints (track_id, seq, x, y, heading_rad, speed_ms, curvature)
|
||||
VALUES ('barcelona-catalunya', 7, 1.05, 1.5, 0, 3.2, 0.7)
|
||||
ON CONFLICT (track_id, seq) DO NOTHING;
|
||||
INSERT INTO track_waypoints (track_id, seq, x, y, heading_rad, speed_ms, curvature)
|
||||
VALUES ('barcelona-catalunya', 8, 1.3, 1.65, 1.5707963267948966, 2.4, 1)
|
||||
ON CONFLICT (track_id, seq) DO NOTHING;
|
||||
INSERT INTO track_waypoints (track_id, seq, x, y, heading_rad, speed_ms, curvature)
|
||||
VALUES ('barcelona-catalunya', 9, 1.15, 1.85, 3.141592653589793, 2.4, 1)
|
||||
ON CONFLICT (track_id, seq) DO NOTHING;
|
||||
INSERT INTO track_waypoints (track_id, seq, x, y, heading_rad, speed_ms, curvature)
|
||||
VALUES ('barcelona-catalunya', 10, 1.4, 2, 2.641592653589793, 3, 0.7)
|
||||
ON CONFLICT (track_id, seq) DO NOTHING;
|
||||
INSERT INTO track_waypoints (track_id, seq, x, y, heading_rad, speed_ms, curvature)
|
||||
VALUES ('barcelona-catalunya', 11, 1.7, 2, 2.141592653589793, 3, 0.7)
|
||||
ON CONFLICT (track_id, seq) DO NOTHING;
|
||||
INSERT INTO track_waypoints (track_id, seq, x, y, heading_rad, speed_ms, curvature)
|
||||
VALUES ('barcelona-catalunya', 12, 1.95, 2.2, 1.5707963267948966, 2.8, 0.5)
|
||||
ON CONFLICT (track_id, seq) DO NOTHING;
|
||||
INSERT INTO track_waypoints (track_id, seq, x, y, heading_rad, speed_ms, curvature)
|
||||
VALUES ('barcelona-catalunya', 13, 1.65, 2.5, 0.3, 2.8, 0.5)
|
||||
ON CONFLICT (track_id, seq) DO NOTHING;
|
||||
INSERT INTO track_waypoints (track_id, seq, x, y, heading_rad, speed_ms, curvature)
|
||||
VALUES ('barcelona-catalunya', 14, 2.2, 2.7, 0.7, 3.2, 0.5)
|
||||
ON CONFLICT (track_id, seq) DO NOTHING;
|
||||
INSERT INTO track_waypoints (track_id, seq, x, y, heading_rad, speed_ms, curvature)
|
||||
VALUES ('barcelona-catalunya', 15, 2.8, 2.7, 1.1, 3.4, 0.5)
|
||||
ON CONFLICT (track_id, seq) DO NOTHING;
|
||||
INSERT INTO track_waypoints (track_id, seq, x, y, heading_rad, speed_ms, curvature)
|
||||
VALUES ('barcelona-catalunya', 16, 3.1, 2.5, 1.9707963267948967, 2.2, 1.4)
|
||||
ON CONFLICT (track_id, seq) DO NOTHING;
|
||||
INSERT INTO track_waypoints (track_id, seq, x, y, heading_rad, speed_ms, curvature)
|
||||
VALUES ('barcelona-catalunya', 17, 2.95, 2.2, 3.541592653589793, 2.2, 1.4)
|
||||
ON CONFLICT (track_id, seq) DO NOTHING;
|
||||
INSERT INTO track_waypoints (track_id, seq, x, y, heading_rad, speed_ms, curvature)
|
||||
VALUES ('barcelona-catalunya', 18, 3.3, 1.9, 0, 4, 0)
|
||||
ON CONFLICT (track_id, seq) DO NOTHING;
|
||||
INSERT INTO track_waypoints (track_id, seq, x, y, heading_rad, speed_ms, curvature)
|
||||
VALUES ('barcelona-catalunya', 19, 4, 1.9, 0, 4, 0)
|
||||
ON CONFLICT (track_id, seq) DO NOTHING;
|
||||
INSERT INTO track_waypoints (track_id, seq, x, y, heading_rad, speed_ms, curvature)
|
||||
VALUES ('barcelona-catalunya', 20, 4.05, 1.6, -1.5707963267948966, 2.4, 1.4)
|
||||
ON CONFLICT (track_id, seq) DO NOTHING;
|
||||
INSERT INTO track_waypoints (track_id, seq, x, y, heading_rad, speed_ms, curvature)
|
||||
VALUES ('barcelona-catalunya', 21, 3.8, 1.4, 3.141592653589793, 2.4, 1.4)
|
||||
ON CONFLICT (track_id, seq) DO NOTHING;
|
||||
INSERT INTO track_waypoints (track_id, seq, x, y, heading_rad, speed_ms, curvature)
|
||||
VALUES ('barcelona-catalunya', 22, 3.5, 1.5, 3.9269908169872414, 2.6, 1)
|
||||
ON CONFLICT (track_id, seq) DO NOTHING;
|
||||
INSERT INTO track_waypoints (track_id, seq, x, y, heading_rad, speed_ms, curvature)
|
||||
VALUES ('barcelona-catalunya', 23, 3.1, 1.25, -1.9707963267948967, 3, 0.7)
|
||||
ON CONFLICT (track_id, seq) DO NOTHING;
|
||||
INSERT INTO track_waypoints (track_id, seq, x, y, heading_rad, speed_ms, curvature)
|
||||
VALUES ('barcelona-catalunya', 24, 2.7, 1, -2.4707963267948965, 3, 0.7)
|
||||
ON CONFLICT (track_id, seq) DO NOTHING;
|
||||
INSERT INTO track_waypoints (track_id, seq, x, y, heading_rad, speed_ms, curvature)
|
||||
VALUES ('barcelona-catalunya', 25, 2.3, 0.7, 3.541592653589793, 3.4, 0.5)
|
||||
ON CONFLICT (track_id, seq) DO NOTHING;
|
||||
INSERT INTO track_waypoints (track_id, seq, x, y, heading_rad, speed_ms, curvature)
|
||||
VALUES ('barcelona-catalunya', 26, 1.6, 0.5, 3.3415926535897933, 3.6, 0.4)
|
||||
ON CONFLICT (track_id, seq) DO NOTHING;
|
||||
INSERT INTO track_waypoints (track_id, seq, x, y, heading_rad, speed_ms, curvature)
|
||||
VALUES ('barcelona-catalunya', 27, 0.9, 0.42, 0, 4, 0)
|
||||
ON CONFLICT (track_id, seq) DO NOTHING;
|
||||
|
||||
INSERT INTO track_tags (track_id, tag) VALUES ('barcelona-catalunya', 'f1')
|
||||
ON CONFLICT DO NOTHING;
|
||||
INSERT INTO track_tags (track_id, tag) VALUES ('barcelona-catalunya', 'balanced')
|
||||
ON CONFLICT DO NOTHING;
|
||||
INSERT INTO track_tags (track_id, tag) VALUES ('barcelona-catalunya', 'testing')
|
||||
ON CONFLICT DO NOTHING;
|
||||
INSERT INTO track_tags (track_id, tag) VALUES ('barcelona-catalunya', 'barcelona')
|
||||
ON CONFLICT DO NOTHING;
|
||||
|
||||
INSERT INTO tracks (id, name, description, author_id, visibility, scale,
|
||||
length_m, width_m, lane_width_m, surface, best_lap_ms, best_lap_holder,
|
||||
bounds_min_x, bounds_min_y, bounds_max_x, bounds_max_y,
|
||||
created_ms, updated_ms)
|
||||
VALUES ('austria-redbull-ring', 'Austria (Red Bull Ring)', 'Red Bull Ring. Short, fast, three straights separated by hairpins.', 'system', 'system', 27,
|
||||
3.5500000000000003, 2, 0.18, 'wood', 0, 'Verstappen',
|
||||
0.3, 0.4, 3.85, 2.4,
|
||||
1700000000000, 1700000000000)
|
||||
ON CONFLICT (id) DO NOTHING;
|
||||
|
||||
INSERT INTO track_waypoints (track_id, seq, x, y, heading_rad, speed_ms, curvature)
|
||||
VALUES ('austria-redbull-ring', 0, 0.3, 0.4, 0, 4.8, 0)
|
||||
ON CONFLICT (track_id, seq) DO NOTHING;
|
||||
INSERT INTO track_waypoints (track_id, seq, x, y, heading_rad, speed_ms, curvature)
|
||||
VALUES ('austria-redbull-ring', 1, 1.6, 0.4, 0, 4.8, 0)
|
||||
ON CONFLICT (track_id, seq) DO NOTHING;
|
||||
INSERT INTO track_waypoints (track_id, seq, x, y, heading_rad, speed_ms, curvature)
|
||||
VALUES ('austria-redbull-ring', 2, 1.85, 0.65, 1.5707963267948966, 2, 1.8)
|
||||
ON CONFLICT (track_id, seq) DO NOTHING;
|
||||
INSERT INTO track_waypoints (track_id, seq, x, y, heading_rad, speed_ms, curvature)
|
||||
VALUES ('austria-redbull-ring', 3, 1.6, 0.95, 3.141592653589793, 2, 1.8)
|
||||
ON CONFLICT (track_id, seq) DO NOTHING;
|
||||
INSERT INTO track_waypoints (track_id, seq, x, y, heading_rad, speed_ms, curvature)
|
||||
VALUES ('austria-redbull-ring', 4, 1.3, 1, 3.641592653589793, 3, 0.7)
|
||||
ON CONFLICT (track_id, seq) DO NOTHING;
|
||||
INSERT INTO track_waypoints (track_id, seq, x, y, heading_rad, speed_ms, curvature)
|
||||
VALUES ('austria-redbull-ring', 5, 1.05, 1.2, -1.5707963267948966, 2.6, 1)
|
||||
ON CONFLICT (track_id, seq) DO NOTHING;
|
||||
INSERT INTO track_waypoints (track_id, seq, x, y, heading_rad, speed_ms, curvature)
|
||||
VALUES ('austria-redbull-ring', 6, 1.4, 1.4, 0, 3.2, 0.5)
|
||||
ON CONFLICT (track_id, seq) DO NOTHING;
|
||||
INSERT INTO track_waypoints (track_id, seq, x, y, heading_rad, speed_ms, curvature)
|
||||
VALUES ('austria-redbull-ring', 7, 1.85, 1.4, 1.7707963267948965, 3.2, 0.5)
|
||||
ON CONFLICT (track_id, seq) DO NOTHING;
|
||||
INSERT INTO track_waypoints (track_id, seq, x, y, heading_rad, speed_ms, curvature)
|
||||
VALUES ('austria-redbull-ring', 8, 2.1, 1.65, 3.141592653589793, 3, 0.7)
|
||||
ON CONFLICT (track_id, seq) DO NOTHING;
|
||||
INSERT INTO track_waypoints (track_id, seq, x, y, heading_rad, speed_ms, curvature)
|
||||
VALUES ('austria-redbull-ring', 9, 2, 1.85, -1.5707963267948966, 3, 0.7)
|
||||
ON CONFLICT (track_id, seq) DO NOTHING;
|
||||
INSERT INTO track_waypoints (track_id, seq, x, y, heading_rad, speed_ms, curvature)
|
||||
VALUES ('austria-redbull-ring', 10, 2.25, 2.05, 0, 2, 1.8)
|
||||
ON CONFLICT (track_id, seq) DO NOTHING;
|
||||
INSERT INTO track_waypoints (track_id, seq, x, y, heading_rad, speed_ms, curvature)
|
||||
VALUES ('austria-redbull-ring', 11, 2.4, 2, 1.5707963267948966, 2, 1.8)
|
||||
ON CONFLICT (track_id, seq) DO NOTHING;
|
||||
INSERT INTO track_waypoints (track_id, seq, x, y, heading_rad, speed_ms, curvature)
|
||||
VALUES ('austria-redbull-ring', 12, 2.4, 2.2, 3.141592653589793, 2, 1.8)
|
||||
ON CONFLICT (track_id, seq) DO NOTHING;
|
||||
INSERT INTO track_waypoints (track_id, seq, x, y, heading_rad, speed_ms, curvature)
|
||||
VALUES ('austria-redbull-ring', 13, 2.2, 2.3, -1.5707963267948966, 2, 1.8)
|
||||
ON CONFLICT (track_id, seq) DO NOTHING;
|
||||
INSERT INTO track_waypoints (track_id, seq, x, y, heading_rad, speed_ms, curvature)
|
||||
VALUES ('austria-redbull-ring', 14, 2.55, 2.4, -0.2, 3.4, 0.4)
|
||||
ON CONFLICT (track_id, seq) DO NOTHING;
|
||||
INSERT INTO track_waypoints (track_id, seq, x, y, heading_rad, speed_ms, curvature)
|
||||
VALUES ('austria-redbull-ring', 15, 3, 2.4, 0, 4, 0)
|
||||
ON CONFLICT (track_id, seq) DO NOTHING;
|
||||
INSERT INTO track_waypoints (track_id, seq, x, y, heading_rad, speed_ms, curvature)
|
||||
VALUES ('austria-redbull-ring', 16, 3.5, 2.4, 0, 4.5, 0)
|
||||
ON CONFLICT (track_id, seq) DO NOTHING;
|
||||
INSERT INTO track_waypoints (track_id, seq, x, y, heading_rad, speed_ms, curvature)
|
||||
VALUES ('austria-redbull-ring', 17, 3.85, 2.15, 1.7707963267948965, 3.4, 0.6)
|
||||
ON CONFLICT (track_id, seq) DO NOTHING;
|
||||
INSERT INTO track_waypoints (track_id, seq, x, y, heading_rad, speed_ms, curvature)
|
||||
VALUES ('austria-redbull-ring', 18, 3.6, 1.8, 3.141592653589793, 3, 0.8)
|
||||
ON CONFLICT (track_id, seq) DO NOTHING;
|
||||
INSERT INTO track_waypoints (track_id, seq, x, y, heading_rad, speed_ms, curvature)
|
||||
VALUES ('austria-redbull-ring', 19, 3.25, 1.85, 3.741592653589793, 3, 0.8)
|
||||
ON CONFLICT (track_id, seq) DO NOTHING;
|
||||
INSERT INTO track_waypoints (track_id, seq, x, y, heading_rad, speed_ms, curvature)
|
||||
VALUES ('austria-redbull-ring', 20, 3, 1.6, -1.9707963267948967, 3.2, 0.6)
|
||||
ON CONFLICT (track_id, seq) DO NOTHING;
|
||||
INSERT INTO track_waypoints (track_id, seq, x, y, heading_rad, speed_ms, curvature)
|
||||
VALUES ('austria-redbull-ring', 21, 2.6, 1.4, -3.141592653589793, 3.4, 0.5)
|
||||
ON CONFLICT (track_id, seq) DO NOTHING;
|
||||
INSERT INTO track_waypoints (track_id, seq, x, y, heading_rad, speed_ms, curvature)
|
||||
VALUES ('austria-redbull-ring', 22, 2, 1.2, 2.641592653589793, 3.6, 0.4)
|
||||
ON CONFLICT (track_id, seq) DO NOTHING;
|
||||
INSERT INTO track_waypoints (track_id, seq, x, y, heading_rad, speed_ms, curvature)
|
||||
VALUES ('austria-redbull-ring', 23, 1.4, 0.8, 2.9415926535897934, 3.8, 0.3)
|
||||
ON CONFLICT (track_id, seq) DO NOTHING;
|
||||
INSERT INTO track_waypoints (track_id, seq, x, y, heading_rad, speed_ms, curvature)
|
||||
VALUES ('austria-redbull-ring', 24, 0.8, 0.5, 0, 4.2, 0.2)
|
||||
ON CONFLICT (track_id, seq) DO NOTHING;
|
||||
|
||||
INSERT INTO track_tags (track_id, tag) VALUES ('austria-redbull-ring', 'f1')
|
||||
ON CONFLICT DO NOTHING;
|
||||
INSERT INTO track_tags (track_id, tag) VALUES ('austria-redbull-ring', 'short')
|
||||
ON CONFLICT DO NOTHING;
|
||||
INSERT INTO track_tags (track_id, tag) VALUES ('austria-redbull-ring', 'fast')
|
||||
ON CONFLICT DO NOTHING;
|
||||
INSERT INTO track_tags (track_id, tag) VALUES ('austria-redbull-ring', 'austria')
|
||||
ON CONFLICT DO NOTHING;
|
||||
|
||||
INSERT INTO tracks (id, name, description, author_id, visibility, scale,
|
||||
length_m, width_m, lane_width_m, surface, best_lap_ms, best_lap_holder,
|
||||
bounds_min_x, bounds_min_y, bounds_max_x, bounds_max_y,
|
||||
created_ms, updated_ms)
|
||||
VALUES ('great-britain-silverstone', 'Great Britain (Silverstone)', 'Silverstone Circuit. Fast, flowing corners; home of British motorsport.', 'system', 'system', 27,
|
||||
3.5500000000000003, 2.4, 0.18, 'carpet', 0, 'Hamilton',
|
||||
0.3, 0.25, 3.85, 2.65,
|
||||
1700000000000, 1700000000000)
|
||||
ON CONFLICT (id) DO NOTHING;
|
||||
|
||||
INSERT INTO track_waypoints (track_id, seq, x, y, heading_rad, speed_ms, curvature)
|
||||
VALUES ('great-britain-silverstone', 0, 0.3, 0.3, 0, 5, 0)
|
||||
ON CONFLICT (track_id, seq) DO NOTHING;
|
||||
INSERT INTO track_waypoints (track_id, seq, x, y, heading_rad, speed_ms, curvature)
|
||||
VALUES ('great-britain-silverstone', 1, 2.4, 0.3, 0, 5, 0)
|
||||
ON CONFLICT (track_id, seq) DO NOTHING;
|
||||
INSERT INTO track_waypoints (track_id, seq, x, y, heading_rad, speed_ms, curvature)
|
||||
VALUES ('great-britain-silverstone', 2, 2.8, 0.45, 1.5707963267948966, 3, 0.8)
|
||||
ON CONFLICT (track_id, seq) DO NOTHING;
|
||||
INSERT INTO track_waypoints (track_id, seq, x, y, heading_rad, speed_ms, curvature)
|
||||
VALUES ('great-britain-silverstone', 3, 2.6, 0.8, 3.141592653589793, 3.4, 0.6)
|
||||
ON CONFLICT (track_id, seq) DO NOTHING;
|
||||
INSERT INTO track_waypoints (track_id, seq, x, y, heading_rad, speed_ms, curvature)
|
||||
VALUES ('great-britain-silverstone', 4, 2.95, 1.05, 2.0707963267948966, 3.2, 0.7)
|
||||
ON CONFLICT (track_id, seq) DO NOTHING;
|
||||
INSERT INTO track_waypoints (track_id, seq, x, y, heading_rad, speed_ms, curvature)
|
||||
VALUES ('great-britain-silverstone', 5, 3.3, 1.3, 0, 2.2, 1.6)
|
||||
ON CONFLICT (track_id, seq) DO NOTHING;
|
||||
INSERT INTO track_waypoints (track_id, seq, x, y, heading_rad, speed_ms, curvature)
|
||||
VALUES ('great-britain-silverstone', 6, 3.6, 1.15, -1.5707963267948966, 2.2, 1.6)
|
||||
ON CONFLICT (track_id, seq) DO NOTHING;
|
||||
INSERT INTO track_waypoints (track_id, seq, x, y, heading_rad, speed_ms, curvature)
|
||||
VALUES ('great-britain-silverstone', 7, 3.6, 0.8, -3.141592653589793, 3, 0.7)
|
||||
ON CONFLICT (track_id, seq) DO NOTHING;
|
||||
INSERT INTO track_waypoints (track_id, seq, x, y, heading_rad, speed_ms, curvature)
|
||||
VALUES ('great-britain-silverstone', 8, 3.85, 0.55, -1.5707963267948966, 2.6, 1)
|
||||
ON CONFLICT (track_id, seq) DO NOTHING;
|
||||
INSERT INTO track_waypoints (track_id, seq, x, y, heading_rad, speed_ms, curvature)
|
||||
VALUES ('great-britain-silverstone', 9, 3.55, 0.25, 0, 2.4, 1)
|
||||
ON CONFLICT (track_id, seq) DO NOTHING;
|
||||
INSERT INTO track_waypoints (track_id, seq, x, y, heading_rad, speed_ms, curvature)
|
||||
VALUES ('great-britain-silverstone', 10, 3.25, 0.25, 1.5707963267948966, 2.4, 1)
|
||||
ON CONFLICT (track_id, seq) DO NOTHING;
|
||||
INSERT INTO track_waypoints (track_id, seq, x, y, heading_rad, speed_ms, curvature)
|
||||
VALUES ('great-britain-silverstone', 11, 3.05, 0.55, 1.8707963267948966, 3.4, 0.5)
|
||||
ON CONFLICT (track_id, seq) DO NOTHING;
|
||||
INSERT INTO track_waypoints (track_id, seq, x, y, heading_rad, speed_ms, curvature)
|
||||
VALUES ('great-britain-silverstone', 12, 2.85, 0.45, 3.141592653589793, 4, 0.3)
|
||||
ON CONFLICT (track_id, seq) DO NOTHING;
|
||||
INSERT INTO track_waypoints (track_id, seq, x, y, heading_rad, speed_ms, curvature)
|
||||
VALUES ('great-britain-silverstone', 13, 1.8, 0.3, 0, 4.6, 0)
|
||||
ON CONFLICT (track_id, seq) DO NOTHING;
|
||||
INSERT INTO track_waypoints (track_id, seq, x, y, heading_rad, speed_ms, curvature)
|
||||
VALUES ('great-britain-silverstone', 14, 1.2, 0.45, -1.7707963267948965, 3.8, 0.4)
|
||||
ON CONFLICT (track_id, seq) DO NOTHING;
|
||||
INSERT INTO track_waypoints (track_id, seq, x, y, heading_rad, speed_ms, curvature)
|
||||
VALUES ('great-britain-silverstone', 15, 1, 0.85, -3.541592653589793, 3.6, 0.5)
|
||||
ON CONFLICT (track_id, seq) DO NOTHING;
|
||||
INSERT INTO track_waypoints (track_id, seq, x, y, heading_rad, speed_ms, curvature)
|
||||
VALUES ('great-britain-silverstone', 16, 0.7, 1.15, 1.8707963267948966, 2.4, 1.2)
|
||||
ON CONFLICT (track_id, seq) DO NOTHING;
|
||||
INSERT INTO track_waypoints (track_id, seq, x, y, heading_rad, speed_ms, curvature)
|
||||
VALUES ('great-britain-silverstone', 17, 0.5, 0.9, 0, 2.6, 0.9)
|
||||
ON CONFLICT (track_id, seq) DO NOTHING;
|
||||
INSERT INTO track_waypoints (track_id, seq, x, y, heading_rad, speed_ms, curvature)
|
||||
VALUES ('great-britain-silverstone', 18, 0.7, 0.65, -1.5707963267948966, 3, 0.7)
|
||||
ON CONFLICT (track_id, seq) DO NOTHING;
|
||||
INSERT INTO track_waypoints (track_id, seq, x, y, heading_rad, speed_ms, curvature)
|
||||
VALUES ('great-britain-silverstone', 19, 0.45, 0.45, -3.541592653589793, 2.6, 1)
|
||||
ON CONFLICT (track_id, seq) DO NOTHING;
|
||||
INSERT INTO track_waypoints (track_id, seq, x, y, heading_rad, speed_ms, curvature)
|
||||
VALUES ('great-britain-silverstone', 20, 0.75, 1, 1.1707963267948966, 2.4, 1)
|
||||
ON CONFLICT (track_id, seq) DO NOTHING;
|
||||
INSERT INTO track_waypoints (track_id, seq, x, y, heading_rad, speed_ms, curvature)
|
||||
VALUES ('great-britain-silverstone', 21, 0.5, 1.5, -3.541592653589793, 2.6, 0.8)
|
||||
ON CONFLICT (track_id, seq) DO NOTHING;
|
||||
INSERT INTO track_waypoints (track_id, seq, x, y, heading_rad, speed_ms, curvature)
|
||||
VALUES ('great-britain-silverstone', 22, 0.3, 1.15, -1.5707963267948966, 2.4, 1)
|
||||
ON CONFLICT (track_id, seq) DO NOTHING;
|
||||
INSERT INTO track_waypoints (track_id, seq, x, y, heading_rad, speed_ms, curvature)
|
||||
VALUES ('great-britain-silverstone', 23, 0.7, 1.6, 0.7853981633974483, 3.4, 0.5)
|
||||
ON CONFLICT (track_id, seq) DO NOTHING;
|
||||
INSERT INTO track_waypoints (track_id, seq, x, y, heading_rad, speed_ms, curvature)
|
||||
VALUES ('great-britain-silverstone', 24, 2, 1.95, 1.9707963267948967, 3, 0.7)
|
||||
ON CONFLICT (track_id, seq) DO NOTHING;
|
||||
INSERT INTO track_waypoints (track_id, seq, x, y, heading_rad, speed_ms, curvature)
|
||||
VALUES ('great-britain-silverstone', 25, 3, 2.4, 3.3415926535897933, 3.4, 0.4)
|
||||
ON CONFLICT (track_id, seq) DO NOTHING;
|
||||
INSERT INTO track_waypoints (track_id, seq, x, y, heading_rad, speed_ms, curvature)
|
||||
VALUES ('great-britain-silverstone', 26, 2.4, 2.65, -1.8707963267948966, 4, 0.3)
|
||||
ON CONFLICT (track_id, seq) DO NOTHING;
|
||||
INSERT INTO track_waypoints (track_id, seq, x, y, heading_rad, speed_ms, curvature)
|
||||
VALUES ('great-britain-silverstone', 27, 1.4, 2.6, -3.141592653589793, 4.4, 0.2)
|
||||
ON CONFLICT (track_id, seq) DO NOTHING;
|
||||
INSERT INTO track_waypoints (track_id, seq, x, y, heading_rad, speed_ms, curvature)
|
||||
VALUES ('great-britain-silverstone', 28, 0.5, 2.3, -2.8415926535897933, 4.8, 0.2)
|
||||
ON CONFLICT (track_id, seq) DO NOTHING;
|
||||
INSERT INTO track_waypoints (track_id, seq, x, y, heading_rad, speed_ms, curvature)
|
||||
VALUES ('great-britain-silverstone', 29, 0.3, 1.7, -1.2707963267948965, 5, 0.1)
|
||||
ON CONFLICT (track_id, seq) DO NOTHING;
|
||||
|
||||
INSERT INTO track_tags (track_id, tag) VALUES ('great-britain-silverstone', 'f1')
|
||||
ON CONFLICT DO NOTHING;
|
||||
INSERT INTO track_tags (track_id, tag) VALUES ('great-britain-silverstone', 'fast')
|
||||
ON CONFLICT DO NOTHING;
|
||||
INSERT INTO track_tags (track_id, tag) VALUES ('great-britain-silverstone', 'flowing')
|
||||
ON CONFLICT DO NOTHING;
|
||||
INSERT INTO track_tags (track_id, tag) VALUES ('great-britain-silverstone', 'silverstone')
|
||||
ON CONFLICT DO NOTHING;
|
||||
|
||||
INSERT INTO tracks (id, name, description, author_id, visibility, scale,
|
||||
length_m, width_m, lane_width_m, surface, best_lap_ms, best_lap_holder,
|
||||
bounds_min_x, bounds_min_y, bounds_max_x, bounds_max_y,
|
||||
created_ms, updated_ms)
|
||||
VALUES ('belgium-spa', 'Belgium (Spa-Francorchamps)', 'Spa-Francorchamps. Long, fast, legendary Eau Rouge / Raidillon.', 'system', 'system', 27,
|
||||
3.85, 2.25, 0.18, 'carpet', 0, 'Verstappen',
|
||||
0.4, 0.5, 4.25, 2.75,
|
||||
1700000000000, 1700000000000)
|
||||
ON CONFLICT (id) DO NOTHING;
|
||||
|
||||
INSERT INTO track_waypoints (track_id, seq, x, y, heading_rad, speed_ms, curvature)
|
||||
VALUES ('belgium-spa', 0, 0.4, 0.5, 0, 4.8, 0)
|
||||
ON CONFLICT (track_id, seq) DO NOTHING;
|
||||
INSERT INTO track_waypoints (track_id, seq, x, y, heading_rad, speed_ms, curvature)
|
||||
VALUES ('belgium-spa', 1, 1.6, 0.5, 0, 4.8, 0)
|
||||
ON CONFLICT (track_id, seq) DO NOTHING;
|
||||
INSERT INTO track_waypoints (track_id, seq, x, y, heading_rad, speed_ms, curvature)
|
||||
VALUES ('belgium-spa', 2, 1.95, 0.6, 0.3, 4.2, 0.5)
|
||||
ON CONFLICT (track_id, seq) DO NOTHING;
|
||||
INSERT INTO track_waypoints (track_id, seq, x, y, heading_rad, speed_ms, curvature)
|
||||
VALUES ('belgium-spa', 3, 2.2, 0.95, 0.9, 4, 0.6)
|
||||
ON CONFLICT (track_id, seq) DO NOTHING;
|
||||
INSERT INTO track_waypoints (track_id, seq, x, y, heading_rad, speed_ms, curvature)
|
||||
VALUES ('belgium-spa', 4, 2.1, 1.3, 3.541592653589793, 4, 0.6)
|
||||
ON CONFLICT (track_id, seq) DO NOTHING;
|
||||
INSERT INTO track_waypoints (track_id, seq, x, y, heading_rad, speed_ms, curvature)
|
||||
VALUES ('belgium-spa', 5, 2.7, 1.5, 0, 5, 0)
|
||||
ON CONFLICT (track_id, seq) DO NOTHING;
|
||||
INSERT INTO track_waypoints (track_id, seq, x, y, heading_rad, speed_ms, curvature)
|
||||
VALUES ('belgium-spa', 6, 3.5, 1.5, 0, 5, 0)
|
||||
ON CONFLICT (track_id, seq) DO NOTHING;
|
||||
INSERT INTO track_waypoints (track_id, seq, x, y, heading_rad, speed_ms, curvature)
|
||||
VALUES ('belgium-spa', 7, 3.85, 1.3, -1.5707963267948966, 2.4, 1.4)
|
||||
ON CONFLICT (track_id, seq) DO NOTHING;
|
||||
INSERT INTO track_waypoints (track_id, seq, x, y, heading_rad, speed_ms, curvature)
|
||||
VALUES ('belgium-spa', 8, 3.6, 1.1, 3.4415926535897934, 2.6, 1.2)
|
||||
ON CONFLICT (track_id, seq) DO NOTHING;
|
||||
INSERT INTO track_waypoints (track_id, seq, x, y, heading_rad, speed_ms, curvature)
|
||||
VALUES ('belgium-spa', 9, 3.3, 1.25, 4.0415926535897935, 2.6, 1.2)
|
||||
ON CONFLICT (track_id, seq) DO NOTHING;
|
||||
INSERT INTO track_waypoints (track_id, seq, x, y, heading_rad, speed_ms, curvature)
|
||||
VALUES ('belgium-spa', 10, 3.5, 1.55, 1.5707963267948966, 3.6, 0.4)
|
||||
ON CONFLICT (track_id, seq) DO NOTHING;
|
||||
INSERT INTO track_waypoints (track_id, seq, x, y, heading_rad, speed_ms, curvature)
|
||||
VALUES ('belgium-spa', 11, 3.25, 1.85, 0, 2.2, 1.6)
|
||||
ON CONFLICT (track_id, seq) DO NOTHING;
|
||||
INSERT INTO track_waypoints (track_id, seq, x, y, heading_rad, speed_ms, curvature)
|
||||
VALUES ('belgium-spa', 12, 3.05, 1.7, -1.5707963267948966, 2.4, 1.4)
|
||||
ON CONFLICT (track_id, seq) DO NOTHING;
|
||||
INSERT INTO track_waypoints (track_id, seq, x, y, heading_rad, speed_ms, curvature)
|
||||
VALUES ('belgium-spa', 13, 3.25, 1.5, 0, 3, 0.7)
|
||||
ON CONFLICT (track_id, seq) DO NOTHING;
|
||||
INSERT INTO track_waypoints (track_id, seq, x, y, heading_rad, speed_ms, curvature)
|
||||
VALUES ('belgium-spa', 14, 3.7, 1.65, 1.8707963267948966, 3.4, 0.5)
|
||||
ON CONFLICT (track_id, seq) DO NOTHING;
|
||||
INSERT INTO track_waypoints (track_id, seq, x, y, heading_rad, speed_ms, curvature)
|
||||
VALUES ('belgium-spa', 15, 4.1, 2, 2.1707963267948966, 4, 0.3)
|
||||
ON CONFLICT (track_id, seq) DO NOTHING;
|
||||
INSERT INTO track_waypoints (track_id, seq, x, y, heading_rad, speed_ms, curvature)
|
||||
VALUES ('belgium-spa', 16, 4.25, 2.4, 3.541592653589793, 4.6, 0.3)
|
||||
ON CONFLICT (track_id, seq) DO NOTHING;
|
||||
INSERT INTO track_waypoints (track_id, seq, x, y, heading_rad, speed_ms, curvature)
|
||||
VALUES ('belgium-spa', 17, 4, 2.7, -1.8707963267948966, 2.4, 1.4)
|
||||
ON CONFLICT (track_id, seq) DO NOTHING;
|
||||
INSERT INTO track_waypoints (track_id, seq, x, y, heading_rad, speed_ms, curvature)
|
||||
VALUES ('belgium-spa', 18, 3.7, 2.55, 3.141592653589793, 2.4, 1.4)
|
||||
ON CONFLICT (track_id, seq) DO NOTHING;
|
||||
INSERT INTO track_waypoints (track_id, seq, x, y, heading_rad, speed_ms, curvature)
|
||||
VALUES ('belgium-spa', 19, 3.55, 2.75, 3.8415926535897933, 2.4, 1.4)
|
||||
ON CONFLICT (track_id, seq) DO NOTHING;
|
||||
INSERT INTO track_waypoints (track_id, seq, x, y, heading_rad, speed_ms, curvature)
|
||||
VALUES ('belgium-spa', 20, 3.05, 2.7, -1.5707963267948966, 2, 1.8)
|
||||
ON CONFLICT (track_id, seq) DO NOTHING;
|
||||
INSERT INTO track_waypoints (track_id, seq, x, y, heading_rad, speed_ms, curvature)
|
||||
VALUES ('belgium-spa', 21, 2.85, 2.45, 0, 2, 1.8)
|
||||
ON CONFLICT (track_id, seq) DO NOTHING;
|
||||
INSERT INTO track_waypoints (track_id, seq, x, y, heading_rad, speed_ms, curvature)
|
||||
VALUES ('belgium-spa', 22, 2, 2.2, 2.8415926535897933, 3.6, 0.3)
|
||||
ON CONFLICT (track_id, seq) DO NOTHING;
|
||||
INSERT INTO track_waypoints (track_id, seq, x, y, heading_rad, speed_ms, curvature)
|
||||
VALUES ('belgium-spa', 23, 1.2, 1.6, 2.541592653589793, 4, 0.2)
|
||||
ON CONFLICT (track_id, seq) DO NOTHING;
|
||||
INSERT INTO track_waypoints (track_id, seq, x, y, heading_rad, speed_ms, curvature)
|
||||
VALUES ('belgium-spa', 24, 0.6, 1.05, 2.8415926535897933, 4.4, 0.2)
|
||||
ON CONFLICT (track_id, seq) DO NOTHING;
|
||||
|
||||
INSERT INTO track_tags (track_id, tag) VALUES ('belgium-spa', 'f1')
|
||||
ON CONFLICT DO NOTHING;
|
||||
INSERT INTO track_tags (track_id, tag) VALUES ('belgium-spa', 'long')
|
||||
ON CONFLICT DO NOTHING;
|
||||
INSERT INTO track_tags (track_id, tag) VALUES ('belgium-spa', 'fast')
|
||||
ON CONFLICT DO NOTHING;
|
||||
INSERT INTO track_tags (track_id, tag) VALUES ('belgium-spa', 'spa')
|
||||
ON CONFLICT DO NOTHING;
|
||||
|
||||
INSERT INTO cars (id, name, owner_id, visibility, scale,
|
||||
length_mm, width_mm, height_mm, weight_g,
|
||||
chassis_model, chassis_material, chassis_printed, chassis_wheelbase_mm, chassis_track_mm,
|
||||
motor_kind, motor_class, motor_kv, motor_power_w,
|
||||
battery_voltage_v, battery_capacity_mah, battery_cells, battery_chemistry,
|
||||
drive, top_speed_ms, color_hex, avatar_url, active,
|
||||
created_ms, updated_ms)
|
||||
VALUES ('f1-2024-redbull-rb20', 'Oracle Red Bull Racing RB20', 'system', 'system', 24,
|
||||
238, 83, 40, 33,
|
||||
'RB20 carbon monocoque', 'carbon-fibre', FALSE, 150, 75,
|
||||
'turbo-hybrid', 'F1 PU', 0, 746000,
|
||||
0, 0, 0, 'li-ion MGU-K',
|
||||
'2WD', 95, '#1e3a8a', '', TRUE,
|
||||
1700000000000, 1700000000000)
|
||||
ON CONFLICT (id) DO NOTHING;
|
||||
|
||||
INSERT INTO cars (id, name, owner_id, visibility, scale,
|
||||
length_mm, width_mm, height_mm, weight_g,
|
||||
chassis_model, chassis_material, chassis_printed, chassis_wheelbase_mm, chassis_track_mm,
|
||||
motor_kind, motor_class, motor_kv, motor_power_w,
|
||||
battery_voltage_v, battery_capacity_mah, battery_cells, battery_chemistry,
|
||||
drive, top_speed_ms, color_hex, avatar_url, active,
|
||||
created_ms, updated_ms)
|
||||
VALUES ('f1-2024-ferrari-sf24', 'Scuderia Ferrari SF-24', 'system', 'system', 24,
|
||||
238, 83, 40, 33,
|
||||
'SF-24 carbon monocoque', 'carbon-fibre', FALSE, 150, 75,
|
||||
'turbo-hybrid', 'F1 PU 066/12', 0, 746000,
|
||||
0, 0, 0, 'li-ion MGU-K',
|
||||
'2WD', 94, '#dc2626', '', TRUE,
|
||||
1700000000000, 1700000000000)
|
||||
ON CONFLICT (id) DO NOTHING;
|
||||
|
||||
INSERT INTO cars (id, name, owner_id, visibility, scale,
|
||||
length_mm, width_mm, height_mm, weight_g,
|
||||
chassis_model, chassis_material, chassis_printed, chassis_wheelbase_mm, chassis_track_mm,
|
||||
motor_kind, motor_class, motor_kv, motor_power_w,
|
||||
battery_voltage_v, battery_capacity_mah, battery_cells, battery_chemistry,
|
||||
drive, top_speed_ms, color_hex, avatar_url, active,
|
||||
created_ms, updated_ms)
|
||||
VALUES ('f1-2024-mclaren-mcl38', 'McLaren MCL38', 'system', 'system', 24,
|
||||
238, 83, 40, 33,
|
||||
'MCL38 carbon monocoque', 'carbon-fibre', FALSE, 150, 75,
|
||||
'turbo-hybrid', 'F1 PU Mercedes-derived', 0, 746000,
|
||||
0, 0, 0, 'li-ion MGU-K',
|
||||
'2WD', 94, '#ea580c', '', TRUE,
|
||||
1700000000000, 1700000000000)
|
||||
ON CONFLICT (id) DO NOTHING;
|
||||
|
||||
INSERT INTO cars (id, name, owner_id, visibility, scale,
|
||||
length_mm, width_mm, height_mm, weight_g,
|
||||
chassis_model, chassis_material, chassis_printed, chassis_wheelbase_mm, chassis_track_mm,
|
||||
motor_kind, motor_class, motor_kv, motor_power_w,
|
||||
battery_voltage_v, battery_capacity_mah, battery_cells, battery_chemistry,
|
||||
drive, top_speed_ms, color_hex, avatar_url, active,
|
||||
created_ms, updated_ms)
|
||||
VALUES ('f1-2024-mercedes-w15', 'Mercedes-AMG W15', 'system', 'system', 24,
|
||||
238, 83, 40, 33,
|
||||
'W15 carbon monocoque', 'carbon-fibre', FALSE, 150, 75,
|
||||
'turbo-hybrid', 'F1 PU M15', 0, 746000,
|
||||
0, 0, 0, 'li-ion MGU-K',
|
||||
'2WD', 94, '#06b6d4', '', TRUE,
|
||||
1700000000000, 1700000000000)
|
||||
ON CONFLICT (id) DO NOTHING;
|
||||
|
||||
INSERT INTO cars (id, name, owner_id, visibility, scale,
|
||||
length_mm, width_mm, height_mm, weight_g,
|
||||
chassis_model, chassis_material, chassis_printed, chassis_wheelbase_mm, chassis_track_mm,
|
||||
motor_kind, motor_class, motor_kv, motor_power_w,
|
||||
battery_voltage_v, battery_capacity_mah, battery_cells, battery_chemistry,
|
||||
drive, top_speed_ms, color_hex, avatar_url, active,
|
||||
created_ms, updated_ms)
|
||||
VALUES ('f1-2024-astonmartin-amr24', 'Aston Martin Aramco AMR24', 'system', 'system', 24,
|
||||
238, 83, 40, 33,
|
||||
'AMR24 carbon monocoque', 'carbon-fibre', FALSE, 150, 75,
|
||||
'turbo-hybrid', 'F1 PU Mercedes-derived', 0, 746000,
|
||||
0, 0, 0, 'li-ion MGU-K',
|
||||
'2WD', 94, '#16a34a', '', TRUE,
|
||||
1700000000000, 1700000000000)
|
||||
ON CONFLICT (id) DO NOTHING;
|
||||
|
||||
@@ -0,0 +1,75 @@
|
||||
-- 004_monaco_rescale.sql
|
||||
-- Replace Monaco centerline (seq 0..23) inserted by 003_f1_seed.sql
|
||||
-- with the new 51-waypoint CSV at D:/x0gp/tracks_waypoints_10x10.csv
|
||||
-- Source CSV: 51 waypoints, scale_xy=0.016 (about 1/62.5), v_scale=sqrt(scale)=0.1265.
|
||||
-- New footprint: 6.46 x 5.37 m, perimeter approx 21.87 m.
|
||||
-- Idempotent: DELETE old waypoints first, UPDATE tracks metadata, INSERT new ones.
|
||||
|
||||
BEGIN;
|
||||
|
||||
DELETE FROM track_waypoints WHERE track_id = 'monaco';
|
||||
|
||||
UPDATE tracks SET
|
||||
length_m = 21.87,
|
||||
width_m = 6.46,
|
||||
bounds_min_x = -3.231,
|
||||
bounds_min_y = -2.684,
|
||||
bounds_max_x = 3.231,
|
||||
bounds_max_y = 2.684,
|
||||
updated_ms = (EXTRACT(EPOCH FROM now()) * 1000)::bigint
|
||||
WHERE id = 'monaco';
|
||||
|
||||
-- New centerline (51 waypoints, scale_xy=0.016, v=0.632 m/s)
|
||||
INSERT INTO track_waypoints (track_id, seq, x, y, heading_rad, speed_ms, curvature) VALUES ('monaco', 0, -3.2064, -1.0454, 1.4710, 0.632, -0.1988);
|
||||
INSERT INTO track_waypoints (track_id, seq, x, y, heading_rad, speed_ms, curvature) VALUES ('monaco', 1, -3.1387, -0.5857, 1.3926, 0.632, -0.1787);
|
||||
INSERT INTO track_waypoints (track_id, seq, x, y, heading_rad, speed_ms, curvature) VALUES ('monaco', 2, -3.0418, -0.1312, 1.3043, 0.632, -0.2544);
|
||||
INSERT INTO track_waypoints (track_id, seq, x, y, heading_rad, speed_ms, curvature) VALUES ('monaco', 3, -2.8946, 0.3084, 1.1557, 0.632, -0.4431);
|
||||
INSERT INTO track_waypoints (track_id, seq, x, y, heading_rad, speed_ms, curvature) VALUES ('monaco', 4, -2.6693, 0.7141, 0.8629, 0.632, -1.0875);
|
||||
INSERT INTO track_waypoints (track_id, seq, x, y, heading_rad, speed_ms, curvature) VALUES ('monaco', 5, -2.3517, 0.9426, 0.1919, 0.632, -1.2844);
|
||||
INSERT INTO track_waypoints (track_id, seq, x, y, heading_rad, speed_ms, curvature) VALUES ('monaco', 6, -1.8935, 0.8648, -0.1182, 0.632, -0.2237);
|
||||
INSERT INTO track_waypoints (track_id, seq, x, y, heading_rad, speed_ms, curvature) VALUES ('monaco', 7, -1.4302, 0.8332, -0.0660, 0.632, 0.0475);
|
||||
INSERT INTO track_waypoints (track_id, seq, x, y, heading_rad, speed_ms, curvature) VALUES ('monaco', 8, -0.9667, 0.8035, -0.0743, 0.632, 0.0756);
|
||||
INSERT INTO track_waypoints (track_id, seq, x, y, heading_rad, speed_ms, curvature) VALUES ('monaco', 9, -0.5052, 0.7644, 0.0045, 0.632, 0.0806);
|
||||
INSERT INTO track_waypoints (track_id, seq, x, y, heading_rad, speed_ms, curvature) VALUES ('monaco', 10, -0.0425, 0.8077, 0.0000, 0.632, -0.0425);
|
||||
INSERT INTO track_waypoints (track_id, seq, x, y, heading_rad, speed_ms, curvature) VALUES ('monaco', 11, 0.4197, 0.7644, -0.0351, 0.632, 0.3650);
|
||||
INSERT INTO track_waypoints (track_id, seq, x, y, heading_rad, speed_ms, curvature) VALUES ('monaco', 12, 0.8809, 0.7753, 0.3862, 0.632, 1.3887);
|
||||
INSERT INTO track_waypoints (track_id, seq, x, y, heading_rad, speed_ms, curvature) VALUES ('monaco', 13, 1.1985, 1.0811, 1.2440, 0.632, 1.4550);
|
||||
INSERT INTO track_waypoints (track_id, seq, x, y, heading_rad, speed_ms, curvature) VALUES ('monaco', 14, 1.1372, 1.5315, 1.5878, 0.632, -0.2144);
|
||||
INSERT INTO track_waypoints (track_id, seq, x, y, heading_rad, speed_ms, curvature) VALUES ('monaco', 15, 1.1839, 1.9468, 1.0284, 0.632, -1.2681);
|
||||
INSERT INTO track_waypoints (track_id, seq, x, y, heading_rad, speed_ms, curvature) VALUES ('monaco', 16, 1.5551, 2.2249, 0.6162, 0.632, -0.4763);
|
||||
INSERT INTO track_waypoints (track_id, seq, x, y, heading_rad, speed_ms, curvature) VALUES ('monaco', 17, 1.9414, 2.4832, 0.5226, 0.632, -0.1756);
|
||||
INSERT INTO track_waypoints (track_id, seq, x, y, heading_rad, speed_ms, curvature) VALUES ('monaco', 18, 2.3526, 2.6842, 0.4546, 0.632, -0.1494);
|
||||
INSERT INTO track_waypoints (track_id, seq, x, y, heading_rad, speed_ms, curvature) VALUES ('monaco', 19, 2.3526, 2.6842, -1.2476, 0.632, -0.0225);
|
||||
INSERT INTO track_waypoints (track_id, seq, x, y, heading_rad, speed_ms, curvature) VALUES ('monaco', 20, 2.4622, 2.3570, -1.2545, 0.632, 0.1775);
|
||||
INSERT INTO track_waypoints (track_id, seq, x, y, heading_rad, speed_ms, curvature) VALUES ('monaco', 21, 2.5976, 1.9356, -0.5751, 0.632, 34.1925);
|
||||
INSERT INTO track_waypoints (track_id, seq, x, y, heading_rad, speed_ms, curvature) VALUES ('monaco', 22, 2.6154, 2.2577, 1.0415, 0.632, -0.8400);
|
||||
INSERT INTO track_waypoints (track_id, seq, x, y, heading_rad, speed_ms, curvature) VALUES ('monaco', 23, 2.9239, 2.4933, -0.0053, 0.632, -3.1975);
|
||||
INSERT INTO track_waypoints (track_id, seq, x, y, heading_rad, speed_ms, curvature) VALUES ('monaco', 24, 3.2311, 2.2544, -1.4159, 0.632, -2.7456);
|
||||
INSERT INTO track_waypoints (track_id, seq, x, y, heading_rad, speed_ms, curvature) VALUES ('monaco', 25, 3.0259, 1.8399, -2.1127, 0.632, -0.6488);
|
||||
INSERT INTO track_waypoints (track_id, seq, x, y, heading_rad, speed_ms, curvature) VALUES ('monaco', 26, 2.7546, 1.4629, -2.2528, 0.632, -0.2769);
|
||||
INSERT INTO track_waypoints (track_id, seq, x, y, heading_rad, speed_ms, curvature) VALUES ('monaco', 27, 2.4413, 1.1199, -2.3708, 0.632, -0.3044);
|
||||
INSERT INTO track_waypoints (track_id, seq, x, y, heading_rad, speed_ms, curvature) VALUES ('monaco', 28, 2.0895, 0.8170, -2.5300, 0.632, -0.3825);
|
||||
INSERT INTO track_waypoints (track_id, seq, x, y, heading_rad, speed_ms, curvature) VALUES ('monaco', 29, 1.6852, 0.5897, -2.7255, 0.632, -0.4019);
|
||||
INSERT INTO track_waypoints (track_id, seq, x, y, heading_rad, speed_ms, curvature) VALUES ('monaco', 30, 1.2447, 0.4437, -2.9031, 0.632, -0.3538);
|
||||
INSERT INTO track_waypoints (track_id, seq, x, y, heading_rad, speed_ms, curvature) VALUES ('monaco', 31, 0.7862, 0.3711, -3.0547, 0.632, -0.3044);
|
||||
INSERT INTO track_waypoints (track_id, seq, x, y, heading_rad, speed_ms, curvature) VALUES ('monaco', 32, 0.3218, 0.3632, 3.0973, 0.632, -0.0975);
|
||||
INSERT INTO track_waypoints (track_id, seq, x, y, heading_rad, speed_ms, curvature) VALUES ('monaco', 33, -0.1396, 0.4121, 3.1387, 0.632, -0.0394);
|
||||
INSERT INTO track_waypoints (track_id, seq, x, y, heading_rad, speed_ms, curvature) VALUES ('monaco', 34, -0.5818, 0.3659, 3.0594, 0.632, -0.2375);
|
||||
INSERT INTO track_waypoints (track_id, seq, x, y, heading_rad, speed_ms, curvature) VALUES ('monaco', 35, -1.0290, 0.4854, 2.9319, 0.632, -0.0950);
|
||||
INSERT INTO track_waypoints (track_id, seq, x, y, heading_rad, speed_ms, curvature) VALUES ('monaco', 36, -1.4880, 0.5588, 2.9664, 0.632, -0.2500);
|
||||
INSERT INTO track_waypoints (track_id, seq, x, y, heading_rad, speed_ms, curvature) VALUES ('monaco', 37, -1.9441, 0.6474, -3.1052, 0.632, 0.8825);
|
||||
INSERT INTO track_waypoints (track_id, seq, x, y, heading_rad, speed_ms, curvature) VALUES ('monaco', 38, -2.3631, 0.5269, -2.4971, 0.632, 1.3600);
|
||||
INSERT INTO track_waypoints (track_id, seq, x, y, heading_rad, speed_ms, curvature) VALUES ('monaco', 39, -2.6181, 0.1409, -1.9547, 0.632, 0.9481);
|
||||
INSERT INTO track_waypoints (track_id, seq, x, y, heading_rad, speed_ms, curvature) VALUES ('monaco', 40, -2.7014, -0.3108, -1.5706, 0.632, 0.3788);
|
||||
INSERT INTO track_waypoints (track_id, seq, x, y, heading_rad, speed_ms, curvature) VALUES ('monaco', 41, -2.6179, -0.7633, -1.6025, 0.632, -0.3425);
|
||||
INSERT INTO track_waypoints (track_id, seq, x, y, heading_rad, speed_ms, curvature) VALUES ('monaco', 42, -2.7299, -1.2092, -1.8788, 0.632, -0.0725);
|
||||
INSERT INTO track_waypoints (track_id, seq, x, y, heading_rad, speed_ms, curvature) VALUES ('monaco', 43, -2.8930, -1.6280, -1.6659, 0.632, 0.7706);
|
||||
INSERT INTO track_waypoints (track_id, seq, x, y, heading_rad, speed_ms, curvature) VALUES ('monaco', 44, -2.8134, -2.0840, -1.2045, 0.632, 0.2162);
|
||||
INSERT INTO track_waypoints (track_id, seq, x, y, heading_rad, speed_ms, curvature) VALUES ('monaco', 45, -2.5685, -2.4739, -1.5682, 0.632, -2.4475);
|
||||
INSERT INTO track_waypoints (track_id, seq, x, y, heading_rad, speed_ms, curvature) VALUES ('monaco', 46, -2.8118, -2.6842, 3.0638, 0.632, -4.0544);
|
||||
INSERT INTO track_waypoints (track_id, seq, x, y, heading_rad, speed_ms, curvature) VALUES ('monaco', 47, -3.1281, -2.4303, 2.0706, 0.632, -1.2500);
|
||||
INSERT INTO track_waypoints (track_id, seq, x, y, heading_rad, speed_ms, curvature) VALUES ('monaco', 48, -3.2004, -1.9728, 1.6822, 0.632, -0.4706);
|
||||
INSERT INTO track_waypoints (track_id, seq, x, y, heading_rad, speed_ms, curvature) VALUES ('monaco', 49, -3.2311, -1.5093, 1.5774, 0.632, -0.2275);
|
||||
INSERT INTO track_waypoints (track_id, seq, x, y, heading_rad, speed_ms, curvature) VALUES ('monaco', 50, -3.2064, -1.0454, 1.4710, 0.632, -0.1988);
|
||||
|
||||
COMMIT;
|
||||
@@ -0,0 +1,90 @@
|
||||
-- 005_races.sql — race plan, finished race archive, queue.
|
||||
--
|
||||
-- Storage split:
|
||||
-- * Active races (lobby/countdown/racing) live in-memory in lobby.Service.
|
||||
-- * Finished races are snapshotted into finished_races on SetRaceStatus(finished).
|
||||
-- * Race plans describe recurring / one-off scheduled races; the scheduler
|
||||
-- materializes them into lobby.RaceMeta as their start_at_ms approaches.
|
||||
-- * Queue entries are per-driver per-race_id subscriptions to the next
|
||||
-- upcoming races. Driver is auto-attached when a slot opens.
|
||||
--
|
||||
-- Keyset pagination:
|
||||
-- * finished_races ordered by (finished_ms DESC, id DESC). Cursor encodes
|
||||
-- (finished_ms, id); lookup uses (finished_ms, id) < (cursor_ms, cursor_id).
|
||||
-- * race_plans ordered by (start_at_ms ASC, id ASC). Cursor is
|
||||
-- (start_at_ms, id) with strict-less comparison.
|
||||
|
||||
CREATE TABLE IF NOT EXISTS finished_races (
|
||||
id TEXT PRIMARY KEY,
|
||||
name TEXT NOT NULL,
|
||||
host_id TEXT NOT NULL,
|
||||
host_name TEXT NOT NULL DEFAULT '',
|
||||
track_id TEXT NOT NULL DEFAULT '',
|
||||
max_cars INT NOT NULL,
|
||||
laps INT NOT NULL,
|
||||
time_limit_s INT NOT NULL,
|
||||
driver_ids TEXT[] NOT NULL DEFAULT '{}',
|
||||
status TEXT NOT NULL DEFAULT 'finished'
|
||||
CHECK (status IN ('finished', 'cancelled')),
|
||||
created_ms BIGINT NOT NULL,
|
||||
started_ms BIGINT NOT NULL DEFAULT 0,
|
||||
finished_ms BIGINT NOT NULL,
|
||||
duration_ms BIGINT NOT NULL DEFAULT 0,
|
||||
total_laps INT NOT NULL DEFAULT 0,
|
||||
total_drivers INT NOT NULL DEFAULT 0,
|
||||
winner_driver_id TEXT NOT NULL DEFAULT '',
|
||||
winner_name TEXT NOT NULL DEFAULT '',
|
||||
best_lap_ms BIGINT NOT NULL DEFAULT 0
|
||||
);
|
||||
|
||||
CREATE INDEX IF NOT EXISTS finished_races_finished_ms_id_idx
|
||||
ON finished_races (finished_ms DESC, id DESC);
|
||||
CREATE INDEX IF NOT EXISTS finished_races_host_idx
|
||||
ON finished_races (host_id);
|
||||
CREATE INDEX IF NOT EXISTS finished_races_track_idx
|
||||
ON finished_races (track_id);
|
||||
CREATE INDEX IF NOT EXISTS finished_races_status_idx
|
||||
ON finished_races (status);
|
||||
|
||||
-- ---------------------------------------------------------------------------
|
||||
-- Race plans
|
||||
-- ---------------------------------------------------------------------------
|
||||
|
||||
CREATE TABLE IF NOT EXISTS race_plans (
|
||||
id TEXT PRIMARY KEY,
|
||||
name TEXT NOT NULL,
|
||||
track_id TEXT NOT NULL DEFAULT 'default',
|
||||
max_cars INT NOT NULL,
|
||||
laps INT NOT NULL DEFAULT 0,
|
||||
time_limit_s INT NOT NULL DEFAULT 0,
|
||||
host_id TEXT NOT NULL,
|
||||
host_name TEXT NOT NULL DEFAULT '',
|
||||
start_at_ms BIGINT NOT NULL,
|
||||
interval_s INT NOT NULL DEFAULT 0, -- 0 = single-shot
|
||||
count INT NOT NULL DEFAULT 0, -- 0 = repeat forever
|
||||
enabled BOOLEAN NOT NULL DEFAULT TRUE,
|
||||
created_ms BIGINT NOT NULL,
|
||||
updated_ms BIGINT NOT NULL,
|
||||
next_fire_ms BIGINT NOT NULL, -- last materialised fire time
|
||||
fires_done INT NOT NULL DEFAULT 0
|
||||
);
|
||||
|
||||
CREATE INDEX IF NOT EXISTS race_plans_start_idx
|
||||
ON race_plans (start_at_ms ASC, id ASC);
|
||||
CREATE INDEX IF NOT EXISTS race_plans_enabled_idx
|
||||
ON race_plans (enabled, next_fire_ms);
|
||||
|
||||
-- ---------------------------------------------------------------------------
|
||||
-- Queue
|
||||
-- ---------------------------------------------------------------------------
|
||||
|
||||
CREATE TABLE IF NOT EXISTS race_queue (
|
||||
driver_id TEXT NOT NULL,
|
||||
race_id TEXT NOT NULL,
|
||||
plan_id TEXT NOT NULL DEFAULT '',
|
||||
enqueued_ms BIGINT NOT NULL,
|
||||
PRIMARY KEY (driver_id, race_id)
|
||||
);
|
||||
|
||||
CREATE INDEX IF NOT EXISTS race_queue_race_idx ON race_queue (race_id);
|
||||
CREATE INDEX IF NOT EXISTS race_queue_driver_idx ON race_queue (driver_id, enqueued_ms);
|
||||
@@ -0,0 +1,12 @@
|
||||
-- 006_drop_host.sql — remove host_id and host_name from race tables.
|
||||
--
|
||||
-- Races no longer carry a host (driver) reference. A race is owned by a
|
||||
-- physical track; the "host" concept is removed from the public API and
|
||||
-- from lobby.RaceMeta. Drivers participate as a flat list of driver_ids.
|
||||
|
||||
ALTER TABLE finished_races DROP COLUMN IF EXISTS host_id;
|
||||
ALTER TABLE finished_races DROP COLUMN IF EXISTS host_name;
|
||||
DROP INDEX IF EXISTS finished_races_host_idx;
|
||||
|
||||
ALTER TABLE race_plans DROP COLUMN IF EXISTS host_id;
|
||||
ALTER TABLE race_plans DROP COLUMN IF EXISTS host_name;
|
||||
@@ -0,0 +1,16 @@
|
||||
-- 007_podium.sql — add podium to finished_races.
|
||||
--
|
||||
-- Podium is the top-3 finishers of a completed race. Stored as JSONB
|
||||
-- (a small ordered list, rarely queried as a relation). Shape per row:
|
||||
-- { "position": 1, "driver_id": "driver-alice",
|
||||
-- "name": "driver-alice", "total_time_ms": 123456 }
|
||||
--
|
||||
-- Ordering: position 1 first.
|
||||
-- GIN index over the jsonb lets future UI filters (e.g. "races won by
|
||||
-- driver X") use @> containment queries without a schema change.
|
||||
|
||||
ALTER TABLE finished_races
|
||||
ADD COLUMN IF NOT EXISTS podium JSONB NOT NULL DEFAULT '[]'::jsonb;
|
||||
|
||||
CREATE INDEX IF NOT EXISTS finished_races_podium_gin
|
||||
ON finished_races USING GIN (podium);
|
||||
@@ -0,0 +1,37 @@
|
||||
-- 008_drivers_clans.sql — drivers and clans.
|
||||
--
|
||||
-- A driver is a person who can join races. Each driver has a unique
|
||||
-- 3-letter nickname (A-Z, uppercase, exactly 3 characters) and an
|
||||
-- optional avatar URL. Drivers can belong to at most one clan.
|
||||
--
|
||||
-- A clan is a team that groups drivers. Each clan has a unique 3-letter
|
||||
-- tag (same rules as the driver nickname) and an optional avatar URL.
|
||||
--
|
||||
-- Constraints:
|
||||
-- * nickname is exactly 3 uppercase ASCII letters and unique.
|
||||
-- * tag is exactly 3 uppercase ASCII letters and unique.
|
||||
-- * driver.clan_id is a soft FK (nullable); ON DELETE SET NULL.
|
||||
|
||||
CREATE TABLE IF NOT EXISTS clans (
|
||||
id TEXT PRIMARY KEY,
|
||||
tag TEXT NOT NULL UNIQUE,
|
||||
name TEXT NOT NULL,
|
||||
avatar_url TEXT NOT NULL DEFAULT '',
|
||||
created_ms BIGINT NOT NULL,
|
||||
updated_ms BIGINT NOT NULL
|
||||
);
|
||||
|
||||
CREATE INDEX IF NOT EXISTS clans_tag_idx ON clans (tag);
|
||||
|
||||
CREATE TABLE IF NOT EXISTS drivers (
|
||||
id TEXT PRIMARY KEY,
|
||||
nickname TEXT NOT NULL UNIQUE,
|
||||
name TEXT NOT NULL,
|
||||
avatar_url TEXT NOT NULL DEFAULT '',
|
||||
clan_id TEXT REFERENCES clans(id) ON DELETE SET NULL,
|
||||
created_ms BIGINT NOT NULL,
|
||||
updated_ms BIGINT NOT NULL
|
||||
);
|
||||
|
||||
CREATE INDEX IF NOT EXISTS drivers_nickname_idx ON drivers (nickname);
|
||||
CREATE INDEX IF NOT EXISTS drivers_clan_idx ON drivers (clan_id);
|
||||
@@ -0,0 +1,68 @@
|
||||
-- 009_live_persistence.sql — persistence for live races and lobby drivers.
|
||||
--
|
||||
-- The active race surface (lobby | countdown | racing) is now mirrored
|
||||
-- in Postgres. finished_races continues to be the canonical archive
|
||||
-- (no rename yet — it stays in the same shape and the next migration
|
||||
-- will unify the two under a single `races` table).
|
||||
--
|
||||
-- live_races
|
||||
-- One row per active race. Status is one of
|
||||
-- lobby | countdown | racing. The `podium` column is reserved for
|
||||
-- future use (we may eventually move finished_podium into this
|
||||
-- table as well).
|
||||
--
|
||||
-- live_race_drivers
|
||||
-- Many-to-many between live_races and drivers. The order column is
|
||||
-- the car's slot in the race (0..max_cars-1).
|
||||
--
|
||||
-- lobby_drivers
|
||||
-- Presence of a driver in the lobby: connected / idle / racing /
|
||||
-- offline and the current race if racing.
|
||||
|
||||
CREATE TABLE IF NOT EXISTS live_races (
|
||||
id TEXT PRIMARY KEY,
|
||||
name TEXT NOT NULL,
|
||||
track_id TEXT NOT NULL,
|
||||
max_cars INT NOT NULL,
|
||||
laps INT NOT NULL,
|
||||
time_limit_s INT NOT NULL,
|
||||
status TEXT NOT NULL DEFAULT 'lobby'
|
||||
CHECK (status IN ('lobby', 'countdown', 'racing', 'cancelled')),
|
||||
created_ms BIGINT NOT NULL,
|
||||
started_ms BIGINT NOT NULL DEFAULT 0,
|
||||
finished_ms BIGINT NOT NULL DEFAULT 0,
|
||||
updated_ms BIGINT NOT NULL
|
||||
);
|
||||
|
||||
CREATE INDEX IF NOT EXISTS live_races_status_idx
|
||||
ON live_races (status, updated_ms DESC);
|
||||
CREATE INDEX IF NOT EXISTS live_races_track_idx
|
||||
ON live_races (track_id);
|
||||
|
||||
CREATE TABLE IF NOT EXISTS live_race_drivers (
|
||||
race_id TEXT NOT NULL REFERENCES live_races(id) ON DELETE CASCADE,
|
||||
driver_id TEXT NOT NULL,
|
||||
slot INT NOT NULL DEFAULT 0,
|
||||
joined_ms BIGINT NOT NULL,
|
||||
PRIMARY KEY (race_id, driver_id)
|
||||
);
|
||||
|
||||
CREATE INDEX IF NOT EXISTS live_race_drivers_driver_idx
|
||||
ON live_race_drivers (driver_id);
|
||||
|
||||
CREATE TABLE IF NOT EXISTS lobby_drivers (
|
||||
driver_id TEXT PRIMARY KEY,
|
||||
name TEXT NOT NULL DEFAULT '',
|
||||
nickname TEXT NOT NULL DEFAULT '',
|
||||
avatar_url TEXT NOT NULL DEFAULT '',
|
||||
clan_id TEXT NOT NULL DEFAULT '',
|
||||
clan_tag TEXT NOT NULL DEFAULT '',
|
||||
status TEXT NOT NULL DEFAULT 'idle'
|
||||
CHECK (status IN ('idle', 'racing', 'offline')),
|
||||
current_race_id TEXT NOT NULL DEFAULT '',
|
||||
connected_ms BIGINT NOT NULL,
|
||||
last_seen_ms BIGINT NOT NULL
|
||||
);
|
||||
|
||||
CREATE INDEX IF NOT EXISTS lobby_drivers_status_idx
|
||||
ON lobby_drivers (status);
|
||||
@@ -0,0 +1,65 @@
|
||||
-- 010_unify_races.sql — unify finished_races and live_races into a single
|
||||
-- `races` table with a 5-state status.
|
||||
--
|
||||
-- After this migration the `races` table holds both the live
|
||||
-- surface (lobby | countdown | racing) and the finished archive
|
||||
-- (finished | cancelled). live_race_drivers keeps the same shape
|
||||
-- (one row per (race, driver)). The former `finished_races` columns
|
||||
-- are kept verbatim; the former `live_races` columns are added
|
||||
-- (started_ms is reused, created_ms was there too).
|
||||
|
||||
-- 1) Rename finished_races -> races.
|
||||
ALTER TABLE finished_races RENAME TO races;
|
||||
|
||||
-- 2) Drop the old finished-only check and replace with a unified one.
|
||||
ALTER TABLE races DROP CONSTRAINT IF EXISTS finished_races_status_check;
|
||||
ALTER TABLE races ADD CONSTRAINT races_status_check
|
||||
CHECK (status IN ('lobby', 'countdown', 'racing', 'finished', 'cancelled'));
|
||||
|
||||
-- 2a) Add the live-only columns to the (former) finished table.
|
||||
ALTER TABLE races ADD COLUMN IF NOT EXISTS updated_ms BIGINT NOT NULL DEFAULT 0;
|
||||
|
||||
-- 3) Drop the old index that referenced the old table name and
|
||||
-- recreate it. The new keyset index sorts on (status, finished_ms
|
||||
-- DESC, id DESC) so the list view can read live+finished together
|
||||
-- when needed.
|
||||
DROP INDEX IF EXISTS finished_races_finished_ms_id_idx;
|
||||
CREATE INDEX IF NOT EXISTS races_status_finished_idx
|
||||
ON races (status, finished_ms DESC, id DESC);
|
||||
DROP INDEX IF EXISTS finished_races_host_idx; -- host_id no longer exists, but the
|
||||
-- index name may have survived. Defensive drop.
|
||||
CREATE INDEX IF NOT EXISTS races_started_idx
|
||||
ON races (status, started_ms DESC, id DESC);
|
||||
|
||||
-- 4) Move live rows from live_races into races BEFORE renaming
|
||||
-- live_race_drivers, so the FK has somewhere to point.
|
||||
INSERT INTO races
|
||||
(id, name, track_id, max_cars, laps, time_limit_s, status,
|
||||
created_ms, started_ms, finished_ms, updated_ms, podium)
|
||||
SELECT
|
||||
id, name, track_id, max_cars, laps, time_limit_s, status,
|
||||
created_ms, started_ms, 0, updated_ms, '[]'::jsonb
|
||||
FROM live_races
|
||||
ON CONFLICT (id) DO UPDATE SET
|
||||
name = EXCLUDED.name,
|
||||
track_id = EXCLUDED.track_id,
|
||||
max_cars = EXCLUDED.max_cars,
|
||||
laps = EXCLUDED.laps,
|
||||
time_limit_s = EXCLUDED.time_limit_s,
|
||||
status = EXCLUDED.status,
|
||||
created_ms = EXCLUDED.created_ms,
|
||||
started_ms = EXCLUDED.started_ms,
|
||||
updated_ms = EXCLUDED.updated_ms;
|
||||
|
||||
-- 5) live_race_drivers: rename to race_drivers and re-target the FK
|
||||
-- at the unified races table.
|
||||
ALTER TABLE live_race_drivers RENAME TO race_drivers;
|
||||
ALTER TABLE race_drivers
|
||||
DROP CONSTRAINT IF EXISTS live_race_drivers_race_id_fkey;
|
||||
ALTER TABLE race_drivers
|
||||
ADD CONSTRAINT race_drivers_race_id_fkey
|
||||
FOREIGN KEY (race_id) REFERENCES races(id) ON DELETE CASCADE;
|
||||
|
||||
-- 6) Drop the now-redundant live tables.
|
||||
DROP TABLE IF EXISTS live_race_drivers;
|
||||
DROP TABLE IF EXISTS live_races;
|
||||
@@ -0,0 +1,373 @@
|
||||
package postgres
|
||||
|
||||
import (
|
||||
"context"
|
||||
"errors"
|
||||
"fmt"
|
||||
|
||||
"github.com/jackc/pgx/v5"
|
||||
"github.com/jackc/pgx/v5/pgconn"
|
||||
"github.com/jackc/pgx/v5/pgxpool"
|
||||
|
||||
"github.com/x0gp/server/internal/catalog"
|
||||
)
|
||||
|
||||
// PgStore implements catalog.Store backed by Postgres + TimescaleDB.
|
||||
type PgStore struct {
|
||||
pool *pgxpool.Pool
|
||||
}
|
||||
|
||||
// NewPgStore wraps an open pool.
|
||||
func NewPgStore(pool *pgxpool.Pool) *PgStore {
|
||||
return &PgStore{pool: pool}
|
||||
}
|
||||
|
||||
// Compile-time check.
|
||||
var _ catalog.Store = (*PgStore)(nil)
|
||||
|
||||
// ---------------------------------------------------------------------------
|
||||
// Load
|
||||
// ---------------------------------------------------------------------------
|
||||
|
||||
// Load reads the full catalog into memory. Used at startup.
|
||||
func (s *PgStore) Load(ctx context.Context) ([]catalog.TrackMeta, []catalog.CarMeta, error) {
|
||||
tracks, err := s.loadTracks(ctx)
|
||||
if err != nil {
|
||||
return nil, nil, fmt.Errorf("load tracks: %w", err)
|
||||
}
|
||||
cars, err := s.loadCars(ctx)
|
||||
if err != nil {
|
||||
return nil, nil, fmt.Errorf("load cars: %w", err)
|
||||
}
|
||||
return tracks, cars, nil
|
||||
}
|
||||
|
||||
func (s *PgStore) loadTracks(ctx context.Context) ([]catalog.TrackMeta, error) {
|
||||
rows, err := s.pool.Query(ctx, `
|
||||
SELECT id, name, description, author_id, visibility, scale,
|
||||
length_m, width_m, lane_width_m, surface,
|
||||
best_lap_ms, best_lap_holder,
|
||||
bounds_min_x, bounds_min_y, bounds_max_x, bounds_max_y,
|
||||
created_ms, updated_ms
|
||||
FROM tracks
|
||||
ORDER BY id`)
|
||||
if err != nil {
|
||||
return nil, err
|
||||
}
|
||||
defer rows.Close()
|
||||
|
||||
out := make([]catalog.TrackMeta, 0)
|
||||
for rows.Next() {
|
||||
var t catalog.TrackMeta
|
||||
if err := rows.Scan(
|
||||
&t.ID, &t.Name, &t.Description, &t.AuthorID, &t.Visibility, &t.Scale,
|
||||
&t.LengthM, &t.WidthM, &t.LaneWidthM, &t.Surface,
|
||||
&t.BestLapMs, &t.BestLapHolder,
|
||||
&t.Bounds.MinX, &t.Bounds.MinY, &t.Bounds.MaxX, &t.Bounds.MaxY,
|
||||
&t.CreatedMs, &t.UpdatedMs,
|
||||
); err != nil {
|
||||
return nil, err
|
||||
}
|
||||
// Derive bounds length/width if not stored explicitly.
|
||||
t.Bounds.LengthM = t.Bounds.MaxX - t.Bounds.MinX
|
||||
t.Bounds.WidthM = t.Bounds.MaxY - t.Bounds.MinY
|
||||
out = append(out, t)
|
||||
}
|
||||
if err := rows.Err(); err != nil {
|
||||
return nil, err
|
||||
}
|
||||
|
||||
// Fetch waypoints and tags per track.
|
||||
for i := range out {
|
||||
wps, err := s.loadWaypoints(ctx, out[i].ID)
|
||||
if err != nil {
|
||||
return nil, fmt.Errorf("waypoints %s: %w", out[i].ID, err)
|
||||
}
|
||||
out[i].Centerline = wps
|
||||
tags, err := s.loadTags(ctx, out[i].ID)
|
||||
if err != nil {
|
||||
return nil, fmt.Errorf("tags %s: %w", out[i].ID, err)
|
||||
}
|
||||
out[i].Tags = tags
|
||||
}
|
||||
return out, nil
|
||||
}
|
||||
|
||||
func (s *PgStore) loadWaypoints(ctx context.Context, trackID string) ([]catalog.Waypoint, error) {
|
||||
rows, err := s.pool.Query(ctx, `
|
||||
SELECT x, y, heading_rad, speed_ms, curvature
|
||||
FROM track_waypoints
|
||||
WHERE track_id = $1
|
||||
ORDER BY seq`, trackID)
|
||||
if err != nil {
|
||||
return nil, err
|
||||
}
|
||||
defer rows.Close()
|
||||
out := make([]catalog.Waypoint, 0)
|
||||
for rows.Next() {
|
||||
var w catalog.Waypoint
|
||||
if err := rows.Scan(&w.X, &w.Y, &w.HeadingRad, &w.SpeedMs, &w.Curvature); err != nil {
|
||||
return nil, err
|
||||
}
|
||||
out = append(out, w)
|
||||
}
|
||||
return out, rows.Err()
|
||||
}
|
||||
|
||||
func (s *PgStore) loadTags(ctx context.Context, trackID string) ([]string, error) {
|
||||
rows, err := s.pool.Query(ctx,
|
||||
`SELECT tag FROM track_tags WHERE track_id = $1 ORDER BY tag`, trackID)
|
||||
if err != nil {
|
||||
return nil, err
|
||||
}
|
||||
defer rows.Close()
|
||||
out := make([]string, 0)
|
||||
for rows.Next() {
|
||||
var tag string
|
||||
if err := rows.Scan(&tag); err != nil {
|
||||
return nil, err
|
||||
}
|
||||
out = append(out, tag)
|
||||
}
|
||||
return out, rows.Err()
|
||||
}
|
||||
|
||||
func (s *PgStore) loadCars(ctx context.Context) ([]catalog.CarMeta, error) {
|
||||
rows, err := s.pool.Query(ctx, `
|
||||
SELECT id, name, owner_id, visibility, scale,
|
||||
length_mm, width_mm, height_mm, weight_g,
|
||||
chassis_model, chassis_material, chassis_printed,
|
||||
chassis_wheelbase_mm, chassis_track_mm,
|
||||
motor_kind, motor_class, motor_kv, motor_power_w,
|
||||
battery_voltage_v, battery_capacity_mah, battery_cells, battery_chemistry,
|
||||
drive, top_speed_ms, color_hex, avatar_url, active,
|
||||
total_distance_m, total_races, total_laps, best_lap_ms,
|
||||
created_ms, updated_ms
|
||||
FROM cars
|
||||
ORDER BY id`)
|
||||
if err != nil {
|
||||
return nil, err
|
||||
}
|
||||
defer rows.Close()
|
||||
out := make([]catalog.CarMeta, 0)
|
||||
for rows.Next() {
|
||||
var c catalog.CarMeta
|
||||
if err := rows.Scan(
|
||||
&c.ID, &c.Name, &c.OwnerID, &c.Visibility, &c.Scale,
|
||||
&c.LengthMm, &c.WidthMm, &c.HeightMm, &c.WeightG,
|
||||
&c.Chassis.Model, &c.Chassis.Material, &c.Chassis.Printed,
|
||||
&c.Chassis.WheelbaseMm, &c.Chassis.TrackMm,
|
||||
&c.Motor.Kind, &c.Motor.Class, &c.Motor.KV, &c.Motor.PowerW,
|
||||
&c.Battery.VoltageV, &c.Battery.CapacityMah, &c.Battery.Cells, &c.Battery.Chemistry,
|
||||
&c.Drive, &c.TopSpeedMs, &c.ColorHex, &c.AvatarURL, &c.Active,
|
||||
&c.TotalDistanceM, &c.TotalRaces, &c.TotalLaps, &c.BestLapMs,
|
||||
&c.CreatedMs, &c.UpdatedMs,
|
||||
); err != nil {
|
||||
return nil, err
|
||||
}
|
||||
out = append(out, c)
|
||||
}
|
||||
return out, rows.Err()
|
||||
}
|
||||
|
||||
// ---------------------------------------------------------------------------
|
||||
// Mutators
|
||||
// ---------------------------------------------------------------------------
|
||||
|
||||
// UpsertTrack writes the track, its waypoints, and its tags in one transaction.
|
||||
func (s *PgStore) UpsertTrack(ctx context.Context, t catalog.TrackMeta) error {
|
||||
tx, err := s.pool.BeginTx(ctx, pgx.TxOptions{})
|
||||
if err != nil {
|
||||
return err
|
||||
}
|
||||
defer tx.Rollback(ctx)
|
||||
|
||||
if _, err := tx.Exec(ctx, `
|
||||
INSERT INTO tracks (id, name, description, author_id, visibility, scale,
|
||||
length_m, width_m, lane_width_m, surface,
|
||||
best_lap_ms, best_lap_holder,
|
||||
bounds_min_x, bounds_min_y, bounds_max_x, bounds_max_y,
|
||||
created_ms, updated_ms)
|
||||
VALUES ($1,$2,$3,$4,$5,$6,$7,$8,$9,$10,$11,$12,$13,$14,$15,$16,$17,$18)
|
||||
ON CONFLICT (id) DO UPDATE SET
|
||||
name = EXCLUDED.name,
|
||||
description = EXCLUDED.description,
|
||||
author_id = EXCLUDED.author_id,
|
||||
visibility = EXCLUDED.visibility,
|
||||
scale = EXCLUDED.scale,
|
||||
length_m = EXCLUDED.length_m,
|
||||
width_m = EXCLUDED.width_m,
|
||||
lane_width_m = EXCLUDED.lane_width_m,
|
||||
surface = EXCLUDED.surface,
|
||||
best_lap_ms = EXCLUDED.best_lap_ms,
|
||||
best_lap_holder = EXCLUDED.best_lap_holder,
|
||||
bounds_min_x = EXCLUDED.bounds_min_x,
|
||||
bounds_min_y = EXCLUDED.bounds_min_y,
|
||||
bounds_max_x = EXCLUDED.bounds_max_x,
|
||||
bounds_max_y = EXCLUDED.bounds_max_y,
|
||||
updated_ms = EXCLUDED.updated_ms`,
|
||||
t.ID, t.Name, t.Description, t.AuthorID, string(t.Visibility), t.Scale,
|
||||
t.LengthM, t.WidthM, t.LaneWidthM, string(t.Surface),
|
||||
t.BestLapMs, t.BestLapHolder,
|
||||
t.Bounds.MinX, t.Bounds.MinY, t.Bounds.MaxX, t.Bounds.MaxY,
|
||||
t.CreatedMs, t.UpdatedMs,
|
||||
); err != nil {
|
||||
return err
|
||||
}
|
||||
|
||||
if _, err := tx.Exec(ctx, `DELETE FROM track_waypoints WHERE track_id = $1`, t.ID); err != nil {
|
||||
return err
|
||||
}
|
||||
for i, w := range t.Centerline {
|
||||
if _, err := tx.Exec(ctx, `
|
||||
INSERT INTO track_waypoints (track_id, seq, x, y, heading_rad, speed_ms, curvature)
|
||||
VALUES ($1, $2, $3, $4, $5, $6, $7)`,
|
||||
t.ID, i, w.X, w.Y, w.HeadingRad, w.SpeedMs, w.Curvature,
|
||||
); err != nil {
|
||||
return err
|
||||
}
|
||||
}
|
||||
|
||||
if _, err := tx.Exec(ctx, `DELETE FROM track_tags WHERE track_id = $1`, t.ID); err != nil {
|
||||
return err
|
||||
}
|
||||
for _, tag := range t.Tags {
|
||||
if _, err := tx.Exec(ctx,
|
||||
`INSERT INTO track_tags (track_id, tag) VALUES ($1, $2)`,
|
||||
t.ID, tag,
|
||||
); err != nil {
|
||||
return err
|
||||
}
|
||||
}
|
||||
|
||||
return tx.Commit(ctx)
|
||||
}
|
||||
|
||||
// DeleteTrack removes a track and all child rows (cascade on FK).
|
||||
func (s *PgStore) DeleteTrack(ctx context.Context, id string) error {
|
||||
_, err := s.pool.Exec(ctx, `DELETE FROM tracks WHERE id = $1`, id)
|
||||
return err
|
||||
}
|
||||
|
||||
// UpsertCar writes a car (insert or update).
|
||||
func (s *PgStore) UpsertCar(ctx context.Context, c catalog.CarMeta) error {
|
||||
_, err := s.pool.Exec(ctx, `
|
||||
INSERT INTO cars (id, name, owner_id, visibility, scale,
|
||||
length_mm, width_mm, height_mm, weight_g,
|
||||
chassis_model, chassis_material, chassis_printed,
|
||||
chassis_wheelbase_mm, chassis_track_mm,
|
||||
motor_kind, motor_class, motor_kv, motor_power_w,
|
||||
battery_voltage_v, battery_capacity_mah, battery_cells, battery_chemistry,
|
||||
drive, top_speed_ms, color_hex, avatar_url, active,
|
||||
total_distance_m, total_races, total_laps, best_lap_ms,
|
||||
created_ms, updated_ms)
|
||||
VALUES ($1,$2,$3,$4,$5,$6,$7,$8,$9,$10,$11,$12,$13,$14,$15,$16,$17,$18,$19,$20,$21,$22,$23,$24,$25,$26,$27,$28,$29,$30,$31,$32)
|
||||
ON CONFLICT (id) DO UPDATE SET
|
||||
name = EXCLUDED.name,
|
||||
owner_id = EXCLUDED.owner_id,
|
||||
visibility = EXCLUDED.visibility,
|
||||
scale = EXCLUDED.scale,
|
||||
length_mm = EXCLUDED.length_mm,
|
||||
width_mm = EXCLUDED.width_mm,
|
||||
height_mm = EXCLUDED.height_mm,
|
||||
weight_g = EXCLUDED.weight_g,
|
||||
chassis_model = EXCLUDED.chassis_model,
|
||||
chassis_material = EXCLUDED.chassis_material,
|
||||
chassis_printed = EXCLUDED.chassis_printed,
|
||||
chassis_wheelbase_mm= EXCLUDED.chassis_wheelbase_mm,
|
||||
chassis_track_mm = EXCLUDED.chassis_track_mm,
|
||||
motor_kind = EXCLUDED.motor_kind,
|
||||
motor_class = EXCLUDED.motor_class,
|
||||
motor_kv = EXCLUDED.motor_kv,
|
||||
motor_power_w = EXCLUDED.motor_power_w,
|
||||
battery_voltage_v = EXCLUDED.battery_voltage_v,
|
||||
battery_capacity_mah= EXCLUDED.battery_capacity_mah,
|
||||
battery_cells = EXCLUDED.battery_cells,
|
||||
battery_chemistry = EXCLUDED.battery_chemistry,
|
||||
drive = EXCLUDED.drive,
|
||||
top_speed_ms = EXCLUDED.top_speed_ms,
|
||||
color_hex = EXCLUDED.color_hex,
|
||||
avatar_url = EXCLUDED.avatar_url,
|
||||
active = EXCLUDED.active,
|
||||
total_distance_m = EXCLUDED.total_distance_m,
|
||||
total_races = EXCLUDED.total_races,
|
||||
total_laps = EXCLUDED.total_laps,
|
||||
best_lap_ms = EXCLUDED.best_lap_ms,
|
||||
updated_ms = EXCLUDED.updated_ms`,
|
||||
c.ID, c.Name, c.OwnerID, string(c.Visibility), c.Scale,
|
||||
c.LengthMm, c.WidthMm, c.HeightMm, c.WeightG,
|
||||
c.Chassis.Model, c.Chassis.Material, c.Chassis.Printed,
|
||||
c.Chassis.WheelbaseMm, c.Chassis.TrackMm,
|
||||
c.Motor.Kind, c.Motor.Class, c.Motor.KV, c.Motor.PowerW,
|
||||
c.Battery.VoltageV, c.Battery.CapacityMah, c.Battery.Cells, c.Battery.Chemistry,
|
||||
string(c.Drive), c.TopSpeedMs, c.ColorHex, c.AvatarURL, c.Active,
|
||||
c.TotalDistanceM, c.TotalRaces, c.TotalLaps, c.BestLapMs,
|
||||
c.CreatedMs, c.UpdatedMs,
|
||||
)
|
||||
return err
|
||||
}
|
||||
|
||||
// DeleteCar removes a car by id.
|
||||
func (s *PgStore) DeleteCar(ctx context.Context, id string) error {
|
||||
_, err := s.pool.Exec(ctx, `DELETE FROM cars WHERE id = $1`, id)
|
||||
return err
|
||||
}
|
||||
|
||||
// UpdateCarStats applies a partial mutation to the stats columns. We
|
||||
// first read the row, run the callback, then write the mutated fields
|
||||
// back. This mirrors the in-memory implementation used by tests.
|
||||
func (s *PgStore) UpdateCarStats(ctx context.Context, id string, fn func(*catalog.CarMeta)) error {
|
||||
tx, err := s.pool.BeginTx(ctx, pgx.TxOptions{})
|
||||
if err != nil {
|
||||
return err
|
||||
}
|
||||
defer tx.Rollback(ctx)
|
||||
|
||||
var c catalog.CarMeta
|
||||
err = tx.QueryRow(ctx, `
|
||||
SELECT id, name, owner_id, visibility, scale,
|
||||
length_mm, width_mm, height_mm, weight_g,
|
||||
chassis_model, chassis_material, chassis_printed,
|
||||
chassis_wheelbase_mm, chassis_track_mm,
|
||||
motor_kind, motor_class, motor_kv, motor_power_w,
|
||||
battery_voltage_v, battery_capacity_mah, battery_cells, battery_chemistry,
|
||||
drive, top_speed_ms, color_hex, avatar_url, active,
|
||||
total_distance_m, total_races, total_laps, best_lap_ms,
|
||||
created_ms, updated_ms
|
||||
FROM cars WHERE id = $1 FOR UPDATE`, id,
|
||||
).Scan(
|
||||
&c.ID, &c.Name, &c.OwnerID, &c.Visibility, &c.Scale,
|
||||
&c.LengthMm, &c.WidthMm, &c.HeightMm, &c.WeightG,
|
||||
&c.Chassis.Model, &c.Chassis.Material, &c.Chassis.Printed,
|
||||
&c.Chassis.WheelbaseMm, &c.Chassis.TrackMm,
|
||||
&c.Motor.Kind, &c.Motor.Class, &c.Motor.KV, &c.Motor.PowerW,
|
||||
&c.Battery.VoltageV, &c.Battery.CapacityMah, &c.Battery.Cells, &c.Battery.Chemistry,
|
||||
&c.Drive, &c.TopSpeedMs, &c.ColorHex, &c.AvatarURL, &c.Active,
|
||||
&c.TotalDistanceM, &c.TotalRaces, &c.TotalLaps, &c.BestLapMs,
|
||||
&c.CreatedMs, &c.UpdatedMs,
|
||||
)
|
||||
if err != nil {
|
||||
if errors.Is(err, pgx.ErrNoRows) {
|
||||
return catalog.ErrNotFound
|
||||
}
|
||||
var pgErr *pgconn.PgError
|
||||
if errors.As(err, &pgErr) {
|
||||
return err
|
||||
}
|
||||
return err
|
||||
}
|
||||
fn(&c)
|
||||
if _, err := tx.Exec(ctx, `
|
||||
UPDATE cars SET
|
||||
total_distance_m = $2,
|
||||
total_races = $3,
|
||||
total_laps = $4,
|
||||
best_lap_ms = $5,
|
||||
updated_ms = $6
|
||||
WHERE id = $1`,
|
||||
c.ID, c.TotalDistanceM, c.TotalRaces, c.TotalLaps, c.BestLapMs, c.UpdatedMs,
|
||||
); err != nil {
|
||||
return err
|
||||
}
|
||||
return tx.Commit(ctx)
|
||||
}
|
||||
@@ -0,0 +1,226 @@
|
||||
// Package postgres owns the persistence layer of the catalog.
|
||||
//
|
||||
// It exposes a *pgxpool.Pool plus a small set of repository helpers used by
|
||||
// internal/catalog. Migrations are applied at startup from the SQL files in
|
||||
// the migrations/ subdirectory.
|
||||
package postgres
|
||||
|
||||
import (
|
||||
"context"
|
||||
"embed"
|
||||
"fmt"
|
||||
"sort"
|
||||
"strings"
|
||||
"time"
|
||||
|
||||
"github.com/jackc/pgx/v5"
|
||||
"github.com/jackc/pgx/v5/pgxpool"
|
||||
)
|
||||
|
||||
//go:embed migrations/*.sql
|
||||
var migrationsFS embed.FS
|
||||
|
||||
// Config captures the connection parameters. URL takes precedence over the
|
||||
// individual fields if non-empty.
|
||||
type Config struct {
|
||||
URL string
|
||||
Host string
|
||||
Port int
|
||||
User string
|
||||
Password string
|
||||
Database string
|
||||
SSLMode string
|
||||
MaxConns int32
|
||||
MinConns int32
|
||||
ConnectTimeout time.Duration
|
||||
}
|
||||
|
||||
// Open establishes a pgxpool, pings the database and returns it. The
|
||||
// returned pool must be closed by the caller.
|
||||
func Open(ctx context.Context, cfg Config) (*pgxpool.Pool, error) {
|
||||
dsn, err := cfg.DSN()
|
||||
if err != nil {
|
||||
return nil, err
|
||||
}
|
||||
|
||||
pcfg, err := pgxpool.ParseConfig(dsn)
|
||||
if err != nil {
|
||||
return nil, fmt.Errorf("parse dsn: %w", err)
|
||||
}
|
||||
if cfg.MaxConns > 0 {
|
||||
pcfg.MaxConns = cfg.MaxConns
|
||||
}
|
||||
if cfg.MinConns > 0 {
|
||||
pcfg.MinConns = cfg.MinConns
|
||||
}
|
||||
if cfg.ConnectTimeout > 0 {
|
||||
pcfg.ConnConfig.ConnectTimeout = cfg.ConnectTimeout
|
||||
}
|
||||
|
||||
pool, err := pgxpool.NewWithConfig(ctx, pcfg)
|
||||
if err != nil {
|
||||
return nil, fmt.Errorf("connect: %w", err)
|
||||
}
|
||||
|
||||
pingCtx, cancel := context.WithTimeout(ctx, 5*time.Second)
|
||||
defer cancel()
|
||||
if err := pool.Ping(pingCtx); err != nil {
|
||||
pool.Close()
|
||||
return nil, fmt.Errorf("ping: %w", err)
|
||||
}
|
||||
return pool, nil
|
||||
}
|
||||
|
||||
// DSN builds the postgres connection string.
|
||||
func (c Config) DSN() (string, error) {
|
||||
if c.URL != "" {
|
||||
return c.URL, nil
|
||||
}
|
||||
if c.Host == "" {
|
||||
return "", fmt.Errorf("postgres: host required")
|
||||
}
|
||||
port := c.Port
|
||||
if port == 0 {
|
||||
port = 5432
|
||||
}
|
||||
ssl := c.SSLMode
|
||||
if ssl == "" {
|
||||
ssl = "disable"
|
||||
}
|
||||
return fmt.Sprintf("postgres://%s:%s@%s:%d/%s?sslmode=%s",
|
||||
c.User, c.Password, c.Host, port, c.Database, ssl), nil
|
||||
}
|
||||
|
||||
// Migrate applies any pending SQL migrations from the embedded migrations/
|
||||
// directory. Migrations are tracked in the schema_migrations table and run
|
||||
// in lexical filename order. Each migration runs in its own transaction.
|
||||
func Migrate(ctx context.Context, pool *pgxpool.Pool) error {
|
||||
if _, err := pool.Exec(ctx, `
|
||||
CREATE TABLE IF NOT EXISTS schema_migrations (
|
||||
version TEXT PRIMARY KEY,
|
||||
applied_at TIMESTAMPTZ NOT NULL DEFAULT now()
|
||||
)`); err != nil {
|
||||
return fmt.Errorf("create schema_migrations: %w", err)
|
||||
}
|
||||
|
||||
entries, err := migrationsFS.ReadDir("migrations")
|
||||
if err != nil {
|
||||
return fmt.Errorf("read migrations: %w", err)
|
||||
}
|
||||
names := make([]string, 0, len(entries))
|
||||
for _, e := range entries {
|
||||
if !e.IsDir() && strings.HasSuffix(e.Name(), ".sql") {
|
||||
names = append(names, e.Name())
|
||||
}
|
||||
}
|
||||
sort.Strings(names)
|
||||
|
||||
applied := map[string]struct{}{}
|
||||
rows, err := pool.Query(ctx, `SELECT version FROM schema_migrations`)
|
||||
if err != nil {
|
||||
return fmt.Errorf("list applied migrations: %w", err)
|
||||
}
|
||||
for rows.Next() {
|
||||
var v string
|
||||
if err := rows.Scan(&v); err != nil {
|
||||
rows.Close()
|
||||
return err
|
||||
}
|
||||
applied[v] = struct{}{}
|
||||
}
|
||||
rows.Close()
|
||||
|
||||
for _, name := range names {
|
||||
if _, ok := applied[name]; ok {
|
||||
continue
|
||||
}
|
||||
body, err := migrationsFS.ReadFile("migrations/" + name)
|
||||
if err != nil {
|
||||
return fmt.Errorf("read %s: %w", name, err)
|
||||
}
|
||||
if err := applyMigration(ctx, pool, name, string(body)); err != nil {
|
||||
return fmt.Errorf("apply %s: %w", name, err)
|
||||
}
|
||||
}
|
||||
return nil
|
||||
}
|
||||
|
||||
func applyMigration(ctx context.Context, pool *pgxpool.Pool, name, body string) error {
|
||||
tx, err := pool.BeginTx(ctx, pgx.TxOptions{})
|
||||
if err != nil {
|
||||
return err
|
||||
}
|
||||
defer tx.Rollback(ctx)
|
||||
|
||||
// pgx's simple-protocol Exec() rejects multi-statement strings. Split
|
||||
// the body on ";\n" boundaries and run each statement individually.
|
||||
for i, stmt := range splitStatements(body) {
|
||||
if _, err := tx.Exec(ctx, stmt); err != nil {
|
||||
preview := stmt
|
||||
if len(preview) > 120 {
|
||||
preview = preview[:120] + "..."
|
||||
}
|
||||
return fmt.Errorf("statement %d failed: %w; sql=%q", i+1, err, preview)
|
||||
}
|
||||
}
|
||||
if _, err := tx.Exec(ctx,
|
||||
`INSERT INTO schema_migrations (version) VALUES ($1)`, name); err != nil {
|
||||
return err
|
||||
}
|
||||
return tx.Commit(ctx)
|
||||
}
|
||||
|
||||
// splitStatements splits a SQL script on top-level ";" boundaries. It
|
||||
// is deliberately simple: it ignores ";" inside string literals and
|
||||
// comments, which is fine for our migration files (no literal ";"
|
||||
// in any INSERT).
|
||||
func splitStatements(body string) []string {
|
||||
var (
|
||||
out []string
|
||||
buf strings.Builder
|
||||
inStr bool
|
||||
escNext bool
|
||||
)
|
||||
for i := 0; i < len(body); i++ {
|
||||
c := body[i]
|
||||
if escNext {
|
||||
buf.WriteByte(c)
|
||||
escNext = false
|
||||
continue
|
||||
}
|
||||
if c == '\\' && inStr {
|
||||
buf.WriteByte(c)
|
||||
escNext = true
|
||||
continue
|
||||
}
|
||||
if c == '\'' {
|
||||
inStr = !inStr
|
||||
buf.WriteByte(c)
|
||||
continue
|
||||
}
|
||||
if c == '-' && !inStr && i+1 < len(body) && body[i+1] == '-' {
|
||||
// line comment until \n
|
||||
for i < len(body) && body[i] != '\n' {
|
||||
buf.WriteByte(body[i])
|
||||
i++
|
||||
}
|
||||
if i < len(body) {
|
||||
buf.WriteByte('\n')
|
||||
}
|
||||
continue
|
||||
}
|
||||
if c == ';' && !inStr {
|
||||
s := strings.TrimSpace(buf.String())
|
||||
if s != "" {
|
||||
out = append(out, s)
|
||||
}
|
||||
buf.Reset()
|
||||
continue
|
||||
}
|
||||
buf.WriteByte(c)
|
||||
}
|
||||
if rest := strings.TrimSpace(buf.String()); rest != "" {
|
||||
out = append(out, rest)
|
||||
}
|
||||
return out
|
||||
}
|
||||
Reference in New Issue
Block a user