stage 0 database schema ready

This commit is contained in:
portakal 2026-05-25 20:07:14 +03:00
commit 7720522a32
18 changed files with 5577 additions and 4 deletions

View file

@ -0,0 +1,336 @@
-- ============================================================================
-- 1. AUTHENTICATION & USERS
-- ============================================================================
-- name: CreateUser :execresult
INSERT INTO users (username, password_hash)
VALUES (?, ?);
-- name: UpdateUserPasswordByUserName :exec
UPDATE users
SET password_hash = ?
WHERE username = ?;
-- name: GetUserByUsername :one
SELECT id, username, password_hash
FROM users
WHERE username = ? LIMIT 1;
-- name: GetUserIdByUsername :one
SELECT id
FROM users
WHERE username = ? LIMIT 1;
-- name: DeleteUserByUsername :exec
UPDATE users
SET deleted_at = CURRENT_TIMESTAMP
WHERE username = ?;
-- name: DeleteAirportByUserName :exec
UPDATE airports
SET is_deleted = TRUE
WHERE user_id = (SELECT id FROM users WHERE username = ?);
-- ============================================================================
-- 2. AIRPORT CORE MANAGEMENT
-- ============================================================================
-- airport row management
-- name: CreateAirportByUserName :execresult
INSERT INTO airports (name, user_id, origin_country_id)
VALUES (?, (SELECT id FROM users WHERE username = ?), ?);
-- name: GetAirportByUserId :one
SELECT id, name, user_id, origin_country_id, cash, current_passengers, max_passenger_capacity, current_fuel, max_fuel_capacity, is_available, player_level, experience_points, passenger_generation_rate, fuel_generation_rate, resources_last_updated_at, is_deleted
FROM airports
WHERE user_id = ? LIMIT 1;
-- name: GetAirportByUserName :one
SELECT id, name, user_id, origin_country_id, cash, current_passengers, max_passenger_capacity, current_fuel, max_fuel_capacity, is_available, player_level, experience_points ,passenger_generation_rate, fuel_generation_rate, resources_last_updated_at, is_deleted
FROM airports
WHERE user_id = (SELECT id FROM users WHERE username = ?) LIMIT 1;
-- airport resource management
-- name: UpdateAirportCurrencies :exec
UPDATE airports
SET cash = ?,
current_passengers = ?,
current_fuel = ?
WHERE id = ?;
-- name: UpdateAirportResources :exec
UPDATE airports
SET
current_fuel = LEAST(
max_fuel_capacity,
current_fuel + (fuel_generation_rate * TIMESTAMPDIFF(SECOND, resources_last_updated_at, NOW()))
),
current_passengers = LEAST(
max_passenger_capacity,
current_passengers + (passenger_generation_rate * TIMESTAMPDIFF(SECOND, resources_last_updated_at, NOW()))
),
resources_last_updated_at = NOW()
WHERE id = ?;
-- name: UpdateAirportCash :exec
UPDATE airports
SET cash = ?
WHERE id = ?;
-- name: UpdateAirportpassengers :exec
UPDATE airports
SET current_passengers = ?
WHERE id = ?;
-- name: UpdateAirportFuel :exec
UPDATE airports
SET current_fuel = ?
WHERE id = ?;
-- name: UpdateAirportmaxPassengers :exec
UPDATE airports
SET max_passenger_capacity = ?
WHERE id = ?;
-- name: UpdateAirportMaxFuel :exec
UPDATE airports
SET max_fuel_capacity = ?
WHERE id = ?;
-- name: UpdateAirportFuelRate :exec
UPDATE airports
SET fuel_generation_rate = ?
WHERE id = ?;
-- name: UpdateAirportPassengerRate :exec
UPDATE airports
SET passenger_generation_rate = ?
WHERE id = ?;
-- name: UpdateAirportResourcesUpdated :exec
update airports
set resources_last_updated_at = ?
where id = ?;
-- name: updatePlayerExperience :exec
UPDATE airports
SET experience_points = ?
WHERE id = ?;
-- name: updatePlayerLevel :exec
UPDATE airports
SET player_level = ?
WHERE id = ?;
-- ============================================================================
-- 3. WAREHOUSE & INVENTORY SYSTEM
-- ============================================================================
-- ============================================================================
-- 4. BUILDINGS & PRODUCTION ENGINE
-- ============================================================================
-- name: addStorageBuilding :execresult
INSERT INTO buildings (name,min_level,construction_cost_cash,capacity,storage_type,storage_subtype)
VALUES (?, ?, ?, ?, ?, ?);
-- name: addOperationalBuilding :execresult
INSERT INTO buildings (name,min_level,construction_cost_cash,operation_type,operation_size)
VALUES (?, ?, ?, ?, ?);
-- name: addPassiveProductionBuilding :execresult
INSERT INTO buildings (name,min_level,construction_cost_cash,passive_type,passive_rate)
VALUES (?, ?, ?, ?, ?);
-- name: addBuilding :execresult
INSERT INTO buildings (name,min_level,construction_cost_cash)
VALUES (?, ?, ?);
-- name: AddBuildingToAirportByUsername :execresult
INSERT INTO airport_buildings (airport_id, building_id)
VALUES ((select id from airports where user_id = (select id from users where username = ?)), ?);
-- name: GetAirportBuildingsByUsername :many
SELECT ab.id AS airport_building_id,b.building_type , b.*
FROM airport_buildings ab
JOIN buildings b ON ab.building_id = b.id
WHERE ab.airport_id = (select id from airports where user_id = (select id from users where username = ?));
-- planes & fleet management
-- name: addPlane :execresult
INSERT INTO planes (name, aircraft_size,operation_type,aircraft_type ,min_level, operation_cost_fuel, operation_cost_cash, max_passengers, travel_time_inSeconds,buying_cost_cash, completed_flight_experience, completed_flight_cash_reward, completed_flight_cargo_reward)
VALUES (?, ?, ?, ?, ?, ?, ?, ?, ?, ?, ?, ?, ?);
-- name: GetPlaneById :one
SELECT * FROM planes WHERE id = ?;
-- name: GetAllPlanes :many
SELECT * FROM planes;
-- name: GetPlanesByOperationType :many
SELECT * FROM planes WHERE operation_type = ?;
-- name: GetPlanesByMinLevel :many
SELECT * FROM planes WHERE min_level <= ?;
-- name: GetPlanesByAircraftSize :many
SELECT * FROM planes WHERE aircraft_size = ?;
-- name: GetPlanesByAircraftType :many
SELECT * FROM planes WHERE aircraft_type = ?;
-- name: addPlaneToAirportByUsername :execresult
INSERT INTO player_planes (airport_id, plane_id, assigned_hangar_id, current_building_id, status)
VALUES ((select id from airports where user_id = (select id from users where username = ?)), ?, ?, ?, 'idle');
-- name: GetPlayerPlanesByUsername :many
SELECT pp.id AS player_plane_id, pp.*
FROM player_planes pp
JOIN planes p ON pp.plane_id = p.id
WHERE pp.airport_id = (select id from airports where user_id = (select id from users where username = ?));
-- name: FindAvailableInfrastructureForPlane :one
SELECT ab.id
FROM airport_buildings ab
JOIN buildings b ON ab.building_id = b.id
LEFT JOIN player_planes pp ON ab.id = pp.current_building_id
WHERE ab.airport_id = (select id from airports where user_id = (select id from users where username = ?))
AND b.operation_type = ? -- 'runway' or 'service' (service bay)
AND b.operation_size = ? -- matches plane's aircraft_size requirement
AND pp.id IS NULL -- Ensures no other plane is physically here right now
LIMIT 1;
-- name: UpdatePlayerPlaneState :exec
UPDATE player_planes
SET current_building_id = ?,
status = ?,
flight_start_time = ?
WHERE id = ?;
-- name: CheckHangarOccupancyByUsername :one
SELECT COUNT(*) AS total_parked
FROM player_planes pp
JOIN airport_buildings ab ON pp.current_building_id = ab.id
WHERE ab.airport_id = (select id from airports where user_id = (select id from users where username = ?))
AND ab.building_id = ?; -- specific hangar
--
-- name: CheckRunwayOccupancyByUsername :one
SELECT COUNT(*) AS total_occupied
FROM player_planes pp
JOIN airport_buildings ab ON pp.current_building_id = ab.id
WHERE ab.airport_id = (select id from airports where user_id = (select id from users where username = ?))
AND ab.building_id = ?; -- specific runway
-- name: GetPlanesReadyToLandByUsername :many
SELECT pp.id AS player_plane_id, pp.airport_id, pp.assigned_hangar_id,
p.completed_flight_experience, p.completed_flight_cash_reward, p.completed_flight_cargo_reward, p.operation_type
FROM player_planes pp
JOIN planes p ON pp.plane_id = p.id
WHERE pp.status = 'flying'
AND ADDTIME(pp.flight_start_time, p.travel_time) <= NOW()
AND pp.airport_id = (select id from airports where user_id = (select id from users where username = ?));
-- ============================================================================
-- 5. FLEET & DYNAMIC INFRASTRUCTURE OPERATIONS
-- ============================================================================
-- name: BuyPlaneForPlayer :execresult
INSERT INTO player_planes (airport_id, plane_id, assigned_hangar_id, current_building_id, status)
VALUES (?, ?, ?, ?, 'idle');
-- name: GetPlayerFleet :many
SELECT pp.id AS player_plane_id, pp.status, pp.updated_at, pp.flight_start_time, pp.current_building_id, pp.assigned_hangar_id,p.*
FROM player_planes pp
JOIN planes p ON pp.plane_id = p.id
WHERE pp.airport_id = ?;
-- name: FindAvailableInfrastructure :one
SELECT ab.id
FROM airport_buildings ab
JOIN buildings b ON ab.building_id = b.id
LEFT JOIN player_planes pp ON ab.id = pp.current_building_id
WHERE ab.airport_id = ?
AND b.operation_type = ? -- 'runway' or 'service' (service bay)
AND b.operation_size = ? -- matches plane's aircraft_size requirement
AND pp.id IS NULL -- Ensures no other plane is physically here right now
LIMIT 1;
-- name: UpdatePlaneState :exec
UPDATE player_planes
SET current_building_id = ?,
status = ?,
flight_start_time = ?
WHERE id = ?;
-- name: CheckHangarOccupancy :one
SELECT COUNT(*) AS total_parked
FROM player_planes
WHERE current_building_id = ?;
-- ============================================================================
-- 6. TIME-BASED FLIGHT ENGINE
-- ============================================================================
-- name: GetPlanesReadyToLand :many
SELECT pp.id AS player_plane_id, pp.airport_id, pp.assigned_hangar_id,
p.completed_flight_experience, p.completed_flight_cash_reward, p.completed_flight_cargo_reward, p.operation_type
FROM player_planes pp
JOIN planes p ON pp.plane_id = p.id
WHERE pp.status = 'flying'
-- Uses your logic: flight_start_time + plane travel duration <= current clock
AND ADDTIME(pp.flight_start_time, p.travel_time) <= NOW();
-- ============================================================================
-- 7. PROGRESSION CONTRACTS & ECONOMY LOGS
-- ============================================================================
-- name: GetActiveContracts :many
SELECT id, title, required_product_id, required_amount, current_amount_delivered, is_completed, expires_at
FROM airport_contracts
WHERE airport_id = ? AND is_completed = FALSE AND expires_at > NOW();
-- name: UpdateContractDelivery :exec
UPDATE airport_contracts
SET current_amount_delivered = current_amount_delivered + ?
WHERE id = ? AND is_completed = FALSE;
-- name: CompleteContract :exec
UPDATE airport_contracts
SET is_completed = TRUE
WHERE id = ?;
-- name: LogCurrencyTransaction :exec
INSERT INTO currency_transaction_logs (airport_id, amount_changed, currency_type, reason)
VALUES (?, ?, ?, ?);
-- name: LogCompletedFlightRoute :exec
INSERT INTO completed_flight_routes_log (origin_airport_id, destination_airport_id, start_time, end_time)
VALUES (?, ?, ?, NOW());

View file

@ -0,0 +1,218 @@
-- ============================================================================
-- 1. AUTHENTICATION & USERS
-- ============================================================================
-- name: CreateUser :execresult
INSERT INTO users (username, password_hash)
VALUES (?, ?);
-- name: UpdateUserPasswordByUserName :exec
UPDATE users
SET password_hash = ?
WHERE username = ?;
-- name: GetUserByUsername :one
SELECT id, username, password_hash, created_at
FROM users
WHERE username = ? LIMIT 1;
-- name: GetUserIdByUsername :one
SELECT id
FROM users
WHERE username = ? LIMIT 1;
-- ============================================================================
-- 2. AIRPORT CORE MANAGEMENT
-- ============================================================================
-- airport row management
-- name: CreateAirportByUserName :execresult
INSERT INTO airports (name, user_id, origin_country_id)
VALUES (?, (SELECT id FROM users WHERE username = ?), ?);
-- name: GetAirportByUserId :one
SELECT id, name, user_id, origin_country_id, cash, current_passengers, max_passenger_capacity, current_fuel, max_fuel_capacity, is_available, player_level, experience_points, passenger_generation_rate, fuel_generation_rate, resources_last_updated_at
FROM airports
WHERE user_id = ? LIMIT 1;
-- name: GetAirportByUserName :one
SELECT id, name, user_id, origin_country_id, cash, current_passengers, max_passenger_capacity, current_fuel, max_fuel_capacity, is_available, player_level, experience_points ,passenger_generation_rate, fuel_generation_rate, resources_last_updated_at
FROM airports
WHERE user_id = (SELECT id FROM users WHERE username = ?) LIMIT 1;
-- airport resource management
-- name: UpdateAirportCurrencies :exec
UPDATE airports
SET cash = ?,
current_passengers = ?,
current_fuel = ?
WHERE id = ?;
-- name: UpdateAirportCash :exec
UPDATE airports
SET cash = ?
WHERE id = ?;
-- name: UpdateAirportpassengers :exec
UPDATE airports
SET current_passengers = ?
WHERE id = ?;
-- name: UpdateAirportFuel :exec
UPDATE airports
SET current_fuel = ?
WHERE id = ?;
-- name: UpdateAirportmaxPassengers :exec
UPDATE airports
SET max_passenger_capacity = ?
WHERE id = ?;
-- name: UpdateAirportMaxFuel :exec
UPDATE airports
SET max_fuel_capacity = ?
WHERE id = ?;
-- name: UpdateAirportFuelRate :exec
UPDATE airports
SET fuel_generation_rate = ?
WHERE id = ?;
-- name: UpdateAirportPassengerRate :exec
UPDATE airports
SET passenger_generation_rate = ?
WHERE id = ?;
-- name: UpdateAirportResourcesUpdated :exec
update airports
set resources_last_updated_at = ?
where id = ?;
-- name: updatePlayerExperience :exec
UPDATE airports
SET experience_points = ?,
WHERE id = ?;
-- name: updatePlayerLevel :exec
UPDATE airports
SET player_level = ?
WHERE id = ?;
-- ============================================================================
-- 3. WAREHOUSE & INVENTORY SYSTEM
-- ============================================================================
-- ============================================================================
-- 4. BUILDINGS & PRODUCTION ENGINE
-- ============================================================================
-- name: addStorageBuilding:execresult
INSERT INTO buildings (name,min_level,construction_cost_cash,capacity,storage_type,storage_subtype)
VALUES (?, ?, ?, ?, ?, ?);
-- name: addOperationalBuilding:execresult
INSERT INTO buildings (name,min_level,construction_cost_cash,operation_type,operation_size)
VALUES (?, ?, ?, ?, ?);
-- name: addPassiveProductionBuilding:execresult
INSERT INTO buildings (name,min_level,construction_cost_cash,currency_type,income_rate)
VALUES (?, ?, ?, ?, ?);
-- name: addProductionBuilding:execresult
INSERT INTO buildings (name,min_level,construction_cost_cash,recipe_id,storage_1,storage_2,storage_3)
VALUES (?, ?, ?, ?, ?, ?, ?);
-- name: AddBuildingToAirport :execresult
INSERT INTO airport_buildings (airport_id, building_id, level)
VALUES ((select id from airports where user_id = (select id from users where username = ?)), ?, 1);
-- name: GetAirportBuildings :many
SELECT ab.id AS airport_building_id, ab.level, b.*
FROM airport_buildings ab
JOIN buildings b ON ab.building_id = b.id
WHERE ab.airport_id = (select id from airports where user_id = (select id from users where username = ?));
-- ============================================================================
-- 5. FLEET & DYNAMIC INFRASTRUCTURE OPERATIONS
-- ============================================================================
-- name: BuyPlaneForPlayer :execresult
INSERT INTO player_planes (airport_id, plane_id, assigned_hangar_id, current_building_id, status)
VALUES (?, ?, ?, ?, 'idle');
-- name: GetPlayerFleet :many
SELECT pp.id AS player_plane_id, pp.status, pp.updated_at, pp.flight_start_time, pp.current_building_id, pp.assigned_hangar_id, pp.assigned_cargo_id,
p.*
FROM player_planes pp
JOIN planes p ON pp.plane_id = p.id
WHERE pp.airport_id = ?;
-- name: FindAvailableInfrastructure :one
SELECT ab.id
FROM airport_buildings ab
JOIN buildings b ON ab.building_id = b.id
LEFT JOIN player_planes pp ON ab.id = pp.current_building_id
WHERE ab.airport_id = ?
AND b.operation_type = ? -- 'runway' or 'service' (service bay)
AND b.operation_size = ? -- matches plane's aircraft_size requirement
AND pp.id IS NULL -- Ensures no other plane is physically here right now
LIMIT 1;
-- name: UpdatePlaneState :exec
UPDATE player_planes
SET current_building_id = ?,
status = ?,
assigned_cargo_id = ?,
flight_start_time = ?
WHERE id = ?;
-- name: CheckHangarOccupancy :one
SELECT COUNT(*) AS total_parked
FROM player_planes
WHERE current_building_id = ?;
-- ============================================================================
-- 6. TIME-BASED FLIGHT ENGINE
-- ============================================================================
-- name: GetPlanesReadyToLand :many
SELECT pp.id AS player_plane_id, pp.airport_id, pp.assigned_hangar_id,
p.completed_flight_experience, p.completed_flight_cash_reward, p.completed_flight_cargo_reward, p.operation_type, pp.assigned_cargo_id
FROM player_planes pp
JOIN planes p ON pp.plane_id = p.id
WHERE pp.status = 'flying'
-- Uses your logic: flight_start_time + plane travel duration <= current clock
AND ADDTIME(pp.flight_start_time, p.travel_time) <= NOW();
-- ============================================================================
-- 7. PROGRESSION CONTRACTS & ECONOMY LOGS
-- ============================================================================
-- name: GetActiveContracts :many
SELECT id, title, required_product_id, required_amount, current_amount_delivered, is_completed, expires_at
FROM airport_contracts
WHERE airport_id = ? AND is_completed = FALSE AND expires_at > NOW();
-- name: UpdateContractDelivery :exec
UPDATE airport_contracts
SET current_amount_delivered = current_amount_delivered + ?
WHERE id = ? AND is_completed = FALSE;
-- name: CompleteContract :exec
UPDATE airport_contracts
SET is_completed = TRUE
WHERE id = ?;
-- name: LogCurrencyTransaction :exec
INSERT INTO currency_transaction_logs (airport_id, amount_changed, currency_type, reason)
VALUES (?, ?, ?, ?);
-- name: LogCompletedFlightRoute :exec
INSERT INTO completed_flight_routes_log (origin_airport_id, destination_country_id, start_time, end_time)
VALUES (?, ?, ?, NOW());

View file

@ -0,0 +1,260 @@
-- stages
-- stage 0 : launch planes to country's base airport (accepts everyhing sendds nothing back)
-- stage 1 : add NPCs and cargo planes and shop buildings.
-- stage 2 : add player progression, building upgrades, effects and more complex recipes.
-- stage 3 : TBD
-- good
CREATE TABLE IF NOT EXISTS users (
id INTEGER PRIMARY KEY AUTO_INCREMENT,
username varchar(255) NOT NULL UNIQUE,
password_hash TEXT NOT NULL,
created_at TIMESTAMP DEFAULT CURRENT_TIMESTAMP,
deleted_at TIMESTAMP DEFAULT NULL
);
-- product table act as a product identifier ie egg, milk, flour etc
create table if not exists products (
id smallint unsigned primary key auto_increment,
name varchar(255) not null
);
-- for stage 2 will not be used
-- increasing speed (crafting,currency type generation etc)),
CREATE table if not exists effects (
id smallint unsigned primary key auto_increment,
name varchar(255) not null
);
-- used airport grouping and for contracts, each country has 3 produce they can export there will not be cap
create table if not exists countries (
id smallint unsigned primary key auto_increment,
name varchar(255) not null,
continent ENUM('void','Africa', 'Antarctica', 'Asia', 'Europe', 'North America', 'Oceania', 'South America') NOT NULL, -- universal enum
produce_1_id smallint unsigned not null,
produce_2_id smallint unsigned not null,
produce_3_id smallint unsigned not null,
foreign key (produce_1_id) references products(id),
foreign key (produce_2_id) references products(id),
foreign key (produce_3_id) references products(id)
);
-- main table
-- primary access table act as a player identifier, each player can only have one airport, but they can have multiple planes and buildings
create table if not exists airports (
id integer unsigned primary key auto_increment,
name varchar(255) not null,
user_id integer unique not null,
origin_country_id smallint unsigned not null,
-- resources
cash bigint unsigned not null default 100,
current_passengers INTEGER UNSIGNED NOT NULL DEFAULT 100,
max_passenger_capacity INTEGER UNSIGNED NOT NULL DEFAULT 100,
current_fuel INTEGER UNSIGNED NOT NULL DEFAULT 500,
max_fuel_capacity INTEGER UNSIGNED NOT NULL DEFAULT 1000,
-- resource generation
fuel_generation_rate INT UNSIGNED NOT NULL DEFAULT 20,
passenger_generation_rate INT UNSIGNED NOT NULL DEFAULT 5,
resources_last_updated_at TIMESTAMP NOT NULL DEFAULT CURRENT_TIMESTAMP,
-- progression
is_available boolean not null default true, -- if true can be sent planes from anyone
player_level integer unsigned not null default 1,
experience_points bigint unsigned not null default 0,
is_deleted BOOLEAN DEFAULT FALSE,
foreign key (origin_country_id) references countries(id),
foreign key (user_id) references users(id),
constraint chk_fuel_capacity CHECK (current_fuel <= max_fuel_capacity),
constraint chk_positive_fuel CHECK (current_fuel >= 0),
CONSTRAINT chk_passenger_capacity CHECK (current_passengers <= max_passenger_capacity),
CONSTRAINT chk_positive_passenger CHECK (current_passengers >= 0)
);
-- for stage 1, used as template for recipes.
create table if not exists recipes (
id integer unsigned primary key auto_increment,
name varchar(255) not null,
ingredient_1_id smallint unsigned ,
ingredient_1_amount integer unsigned ,
ingredient_2_id smallint unsigned,
ingredient_2_amount integer unsigned ,
ingredient_3_id smallint unsigned ,
ingredient_3_amount integer unsigned ,
product_id smallint unsigned not null,
yield_amount integer unsigned not null,
foreign key (ingredient_1_id) references products(id),
foreign key (ingredient_2_id) references products(id),
foreign key (ingredient_3_id) references products(id),
foreign key (product_id) references products(id)
);
-- BUILDNGS
-- hangars fuel tanks etc
CREATE table if not exists buildings (
-- shared
id integer unsigned primary key auto_increment,
name varchar(255) not null,
min_level integer unsigned not null DEfAULT 1,
construction_cost_cash integer unsigned not null default 100,
upgrade_tier TINYINT UNSIGNED DEFAULT 0,
upgrade_cost_cash_to_uptier integer unsigned default null,
building_type ENUM('none','storage', 'support', 'operation', 'passive', 'shop', 'production') not null,
-- production specific
-- storage
capacity integer unsigned ,
storage_type ENUM( 'fuel' , 'plane', 'product'),
storage_subtype ENUM('none', 'airplane', 'helicopter', 'seaplane','spaceship'),
-- support
effect_id smallint unsigned,
effect_value integer,
-- operation
operation_size enum('small','medium' ,'large', 'huge'),
operation_type enum('runway', 'service', 'production'),
-- passive income
passive_type enum('passengers', 'fuel'),
passive_rate integer ,
foreign key (effect_id) references effects(id)
);
-- stage 1
create table if not exists building_products (
id integer unsigned primary key auto_increment,
building_id integer unsigned not null,
recipe_id integer unsigned,
storage_product integer unsigned ,
storage_1 integer unsigned ,
storage_2 integer unsigned ,
storage_3 integer unsigned ,
foreign key (building_id) references buildings(id),
foreign key (recipe_id) references recipes(id)
);
-- many to many relation between airport and buildings
create table if not exists airport_buildings (
id integer unsigned primary key auto_increment,
airport_id integer unsigned not null,
building_id integer unsigned not null,
-- shop specific
recipe_id integer unsigned ,
storage_product integer unsigned ,
storage_1 integer unsigned ,
storage_2 integer unsigned ,
storage_3 integer unsigned ,
level integer unsigned not null default 1,
foreign key (airport_id) references airports(id) ,
foreign key (building_id) references buildings(id)
);
-- planes
-- template for planes
create table if not exists planes (
id integer unsigned primary key auto_increment,
name varchar(255) not null,
min_level integer unsigned not null default 1,
operation_cost_fuel integer unsigned not null,
operation_cost_cash integer unsigned not null DEFAULT 10,
max_passengers integer unsigned,
travel_time_inSeconds integer unsigned not null,
operation_type enum('passenger', 'cargo') not null,
aircraft_size enum('small', 'medium', 'large', 'huge') not null,
aircraft_type enum('plane', 'helicopter', 'seaplane','spaceship') not null,
buying_cost_cash integer unsigned not null DEFAULT 100,
completed_flight_experience integer unsigned not null DEFAULT 20,
completed_flight_cash_reward integer unsigned DEFAULT 50,
completed_flight_cargo_reward integer unsigned DEFAULT null
);
-- actual planes owned by players, tracks location, status, assigned hangar etc
CREATE TABLE IF NOT EXISTS player_planes (
id INT UNSIGNED PRIMARY KEY AUTO_INCREMENT,
airport_id INT UNSIGNED NOT NULL,
plane_id INTEGER UNSIGNED NOT NULL,
-- 1. assignment (Must always point to a hangar they own they move between suitable hangars)
assigned_hangar_id INT UNSIGNED NOT NULL,
-- 2. Real-time physical location (stored, Service Bay, Runway, or NULL if flying)
current_building_id INT UNSIGNED DEFAULT NULL,
-- assigned_cargo_id INTEGER UNSIGNED DEFAULT NULL, -- stage 1 For cargo planes, track what they're carrying
status ENUM('idle', 'maintenance', 'boarding', 'taxiing', 'flying') NOT NULL DEFAULT 'idle',
updated_at TIMESTAMP DEFAULT CURRENT_TIMESTAMP ON UPDATE CURRENT_TIMESTAMP,
flight_start_time TIMESTAMP NULL DEFAULT NULL,
FOREIGN KEY (airport_id) REFERENCES airports(id),
FOREIGN KEY (plane_id) REFERENCES planes(id),
FOREIGN KEY (assigned_hangar_id) REFERENCES airport_buildings(id),
FOREIGN KEY (current_building_id) REFERENCES airport_buildings(id)
);
-- stage 1
CREATE TABLE IF NOT EXISTS airport_inventory (
airport_id INTEGER unsigned NOT NULL,
product_id SMALLINT UNSIGNED NOT NULL,
quantity INTEGER UNSIGNED NOT NULL DEFAULT 0,
PRIMARY KEY (airport_id, product_id),
FOREIGN KEY (airport_id) REFERENCES airports(id),
FOREIGN KEY (product_id) REFERENCES products(id)
);
-- stage ? tbd
CREATE TABLE IF NOT EXISTS airport_contracts (
id INTEGER UNSIGNED PRIMARY KEY AUTO_INCREMENT,
airport_id INTEGER unsigned NOT NULL,
title VARCHAR(255) NOT NULL,
-- What they need to deliver
required_product_id SMALLINT UNSIGNED NOT NULL,
required_amount INTEGER UNSIGNED NOT NULL,
current_amount_delivered INTEGER UNSIGNED NOT NULL DEFAULT 0,
-- Status
is_completed BOOLEAN NOT NULL DEFAULT FALSE,
expires_at TIMESTAMP NOT NULL,
FOREIGN KEY (airport_id) REFERENCES airports(id),
FOREIGN KEY (required_product_id) REFERENCES products(id)
);
-- logs
create table if not exists completed_flight_routes_log (
id integer unsigned primary key auto_increment,
origin_airport_id integer unsigned not null,
destination_airport_id integer unsigned not null,
start_time timestamp not null default current_timestamp,
end_time timestamp default null,
foreign key (origin_airport_id) references airports(id),
foreign key (destination_airport_id) references airports(id)
);
CREATE TABLE IF NOT EXISTS currency_transaction_logs (
id BIGINT UNSIGNED PRIMARY KEY AUTO_INCREMENT,
airport_id INT UNSIGNED NOT NULL,
amount_changed INT NOT NULL, -- Negative for buying, positive for earning
currency_type ENUM('cash', 'fuel', 'passengers') NOT NULL,
reason VARCHAR(255) NOT NULL, -- e.g., 'bought_plane_id_12', 'completed_flight_34'
created_at TIMESTAMP DEFAULT CURRENT_TIMESTAMP,
FOREIGN KEY (airport_id) REFERENCES airports(id)
);

View file

@ -0,0 +1,254 @@
-- stages
-- stage 0 : launch planes to country's base airport (accepts everyhing sendds nothing back)
-- stage 1 : add NPCs and cargo planes and shop buildings.
-- stage 2 : add player progression, building upgrades, effects and more complex recipes.
-- stage 3 : TBD
-- good
CREATE TABLE IF NOT EXISTS users (
id INTEGER PRIMARY KEY AUTO_INCREMENT,
username varchar(255) NOT NULL UNIQUE,
password_hash TEXT NOT NULL,
created_at TIMESTAMP DEFAULT CURRENT_TIMESTAMP
);
-- product table act as a product identifier ie egg, milk, flour etc
create table if not exists products (
id smallint unsigned primary key auto_increment,
name varchar(255) not null
);
-- for stage 2 will not be used
-- increasing speed (crafting,currency type generation etc)),
CREATE table if not exists effects (
id smallint unsigned primary key auto_increment,
name varchar(255) not null
);
-- used airport grouping and for contracts, each country has 3 produce they can export there will not be cap
create table if not exists countries (
id smallint unsigned primary key auto_increment,
name varchar(255) not null,
continent ENUM('void','Africa', 'Antarctica', 'Asia', 'Europe', 'North America', 'Oceania', 'South America') NOT NULL, -- universal enum
produce_1_id smallint unsigned not null,
produce_2_id smallint unsigned not null,
produce_3_id smallint unsigned not null,
foreign key (produce_1_id) references products(id),
foreign key (produce_2_id) references products(id),
foreign key (produce_3_id) references products(id)
);
-- main table
-- primary access table act as a player identifier, each player can only have one airport, but they can have multiple planes and buildings
create table if not exists airports (
id integer unsigned primary key auto_increment,
name varchar(255) not null,
user_id integer unique not null,
origin_country_id smallint unsigned not null,
-- resources
cash bigint unsigned not null default 100,
current_passengers INTEGER UNSIGNED NOT NULL DEFAULT 100,
max_passenger_capacity INTEGER UNSIGNED NOT NULL DEFAULT 100,
current_fuel INTEGER UNSIGNED NOT NULL DEFAULT 500,
max_fuel_capacity INTEGER UNSIGNED NOT NULL DEFAULT 1000,
-- resource generation
fuel_generation_rate INT UNSIGNED NOT NULL DEFAULT 20,
passenger_generation_rate INT UNSIGNED NOT NULL DEFAULT 5,
resources_last_updated_at TIMESTAMP NOT NULL DEFAULT CURRENT_TIMESTAMP,
-- progression
is_available boolean not null default true, -- if true can be sent planes from anyone
player_level integer unsigned not null default 1,
experience_points bigint unsigned not null default 0,
foreign key (origin_country_id) references countries(id),
foreign key (user_id) references users(id),
constraint chk_fuel_capacity CHECK (current_fuel <= max_fuel_capacity),
constraint chk_positive_fuel CHECK (current_fuel >= 0)
);
-- for stage 1, used as template for recipes.
create table if not exists recipes (
id integer unsigned primary key auto_increment,
name varchar(255) not null,
ingredient_1_id smallint unsigned ,
ingredient_1_amount integer unsigned ,
ingredient_2_id smallint unsigned,
ingredient_2_amount integer unsigned ,
ingredient_3_id smallint unsigned ,
ingredient_3_amount integer unsigned ,
product_id smallint unsigned not null,
yield_amount integer unsigned not null,
foreign key (ingredient_1_id) references products(id),
foreign key (ingredient_2_id) references products(id),
foreign key (ingredient_3_id) references products(id),
foreign key (product_id) references products(id)
);
-- BUILDNGS
-- hangars fuel tanks etc
CREATE table if not exists buildings (
-- shared
id integer unsigned primary key auto_increment,
name varchar(255) not null,
min_level integer unsigned not null DEfAULT 1,
construction_cost_cash integer unsigned not null default 100,
upgrade_tier TINYINT UNSIGNED DEFAULT 0,
upgrade_cost_cash_to_uptier integer unsigned default null,
-- storage
capacity integer unsigned ,
storage_type ENUM( 'fuel' , 'plane', 'product'),
storage_subtype ENUM('none', 'airplane', 'helicopter', 'seaplane','spaceship'),
-- support
effect_id smallint unsigned,
effect_value integer,
-- operation
operation_size enum('small','medium' ,'large', 'huge'),
operation_type enum('runway', 'service', 'production'),
-- passive income
passive_type enum('passengers', 'fuel'),
passive_rate integer ,
foreign key (effect_id) references effects(id)
);
--stage 1
create table if not exists building_products (
id integer unsigned primary key auto_increment,
building_id integer unsigned not null,
recipe_id integer unsigned,
storage_product integer unsigned ,
storage_1 integer unsigned ,
storage_2 integer unsigned ,
storage_3 integer unsigned ,
foreign key (building_id) references buildings(id),
foreign key (recipe_id) references recipes(id)
);
-- many to many relation between airport and buildings
create table if not exists airport_buildings (
id integer unsigned primary key auto_increment,
airport_id integer unsigned not null,
building_id integer unsigned not null,
-- shop specific
recipe_id integer unsigned ,
storage_product integer unsigned ,
storage_1 integer unsigned ,
storage_2 integer unsigned ,
storage_3 integer unsigned ,
level integer unsigned not null default 1,
foreign key (airport_id) references airports(id) ,
foreign key (building_id) references buildings(id)
);
-- planes
-- template for planes
create table if not exists planes (
id integer unsigned primary key auto_increment,
name varchar(255) not null,
min_level integer unsigned not null default 1,
operation_cost_fuel integer unsigned not null,
operation_cost_cash integer unsigned not null DEFAULT 10,
max_passengers integer unsigned,
travel_time_inSeconds integer unsigned not null,
operation_type enum('passenger', 'cargo') not null,
aircraft_size enum('small', 'medium', 'large', 'huge') not null,
aircraft_type enum('plane', 'helicopter', 'seaplane','spaceship') not null,
buying_cost_cash integer unsigned not null DEFAULT 100,
completed_flight_experience integer unsigned not null DEFAULT 20,
completed_flight_cash_reward integer unsigned DEFAULT 50,
completed_flight_cargo_reward integer unsigned DEFAULT 10
);
-- actual planes owned by players, tracks location, status, assigned hangar etc
CREATE TABLE IF NOT EXISTS player_planes (
id INT UNSIGNED PRIMARY KEY AUTO_INCREMENT,
airport_id INT UNSIGNED NOT NULL,
plane_id INTEGER UNSIGNED NOT NULL,
-- 1. assignment (Must always point to a hangar they own they move between suitable hangars)
assigned_hangar_id INT UNSIGNED NOT NULL,
-- 2. Real-time physical location (stored, Service Bay, Runway, or NULL if flying)
current_building_id INT UNSIGNED DEFAULT NULL,
-- assigned_cargo_id INTEGER UNSIGNED DEFAULT NULL, -- stage 1 For cargo planes, track what they're carrying
status ENUM('idle', 'maintenance', 'boarding', 'taxiing', 'flying') NOT NULL DEFAULT 'idle',
updated_at TIMESTAMP DEFAULT CURRENT_TIMESTAMP ON UPDATE CURRENT_TIMESTAMP,
flight_start_time TIMESTAMP NULL DEFAULT NULL,
FOREIGN KEY (airport_id) REFERENCES airports(id),
FOREIGN KEY (plane_id) REFERENCES planes(id),
FOREIGN KEY (assigned_hangar_id) REFERENCES airport_buildings(id),
FOREIGN KEY (current_building_id) REFERENCES airport_buildings(id)
--foreign key (assigned_cargo_id) references products(id) -- stage 1
);
-- stage 1
CREATE TABLE IF NOT EXISTS airport_inventory (
airport_id INTEGER unsigned NOT NULL,
product_id SMALLINT UNSIGNED NOT NULL,
quantity INTEGER UNSIGNED NOT NULL DEFAULT 0,
PRIMARY KEY (airport_id, product_id),
FOREIGN KEY (airport_id) REFERENCES airports(id),
FOREIGN KEY (product_id) REFERENCES products(id)
);
-- stage ? tbd
CREATE TABLE IF NOT EXISTS airport_contracts (
id INTEGER UNSIGNED PRIMARY KEY AUTO_INCREMENT,
airport_id INTEGER unsigned NOT NULL,
title VARCHAR(255) NOT NULL,
-- What they need to deliver
required_product_id SMALLINT UNSIGNED NOT NULL,
required_amount INTEGER UNSIGNED NOT NULL,
current_amount_delivered INTEGER UNSIGNED NOT NULL DEFAULT 0,
-- Status
is_completed BOOLEAN NOT NULL DEFAULT FALSE,
expires_at TIMESTAMP NOT NULL,
FOREIGN KEY (airport_id) REFERENCES airports(id),
FOREIGN KEY (required_product_id) REFERENCES products(id)
);
-- logs
create table if not exists completed_flight_routes_log (
id integer unsigned primary key auto_increment,
origin_airport_id integer unsigned not null,
destination_airport_id integer unsigned not null,
start_time timestamp not null default current_timestamp,
end_time timestamp default null,
foreign key (origin_airport_id) references airports(id),
foreign key (destination_airport_id) references airports(id)
);
CREATE TABLE IF NOT EXISTS currency_transaction_logs (
id BIGINT UNSIGNED PRIMARY KEY AUTO_INCREMENT,
airport_id INT UNSIGNED NOT NULL,
amount_changed INT NOT NULL, -- Negative for buying, positive for earning
currency_type ENUM('cash', 'fuel', 'passengers') NOT NULL,
reason VARCHAR(255) NOT NULL, -- e.g., 'bought_plane_id_12', 'completed_flight_34'
created_at TIMESTAMP DEFAULT CURRENT_TIMESTAMP,
FOREIGN KEY (airport_id) REFERENCES airports(id)
);

View file

@ -0,0 +1,9 @@
version: "2"
sql:
- engine: "mysql"
queries: "queries.sql"
schema: "schema.sql"
gen:
go:
package: "db"
out: "../"