feature: Markets and shopping features

This commit is contained in:
Keith Solomon
2026-02-13 06:57:13 -06:00
parent 5e60919e01
commit 714c291c8b
4 changed files with 753 additions and 0 deletions

View File

@@ -68,6 +68,23 @@ class SpacetradersStorage {
'CREATE INDEX IF NOT EXISTS idx_api_cache_expires
ON api_cache (expires_at)'
);
$this->db->exec(
'CREATE TABLE IF NOT EXISTS market_scan_waypoints (
system_symbol TEXT NOT NULL,
waypoint_symbol TEXT NOT NULL,
exports_json TEXT NOT NULL,
probe_ship_symbol TEXT NOT NULL,
error_message TEXT NOT NULL,
updated_at INTEGER NOT NULL,
PRIMARY KEY (system_symbol, waypoint_symbol)
)'
);
$this->db->exec(
'CREATE INDEX IF NOT EXISTS idx_market_scan_system_updated
ON market_scan_waypoints (system_symbol, updated_at)'
);
}
/**
@@ -243,4 +260,99 @@ class SpacetradersStorage {
public function clearAllCache(): void {
$this->db->exec( 'DELETE FROM api_cache' );
}
/**
* Store scanned export data for a marketplace waypoint.
*
* @param string $systemSymbol System symbol.
* @param string $waypointSymbol Waypoint symbol.
* @param array<int,array<string,mixed>> $exports Scanned export records.
* @param string $probeShipSymbol Probe ship symbol used for scan.
* @param string $errorMessage Optional scan error message.
*
* @return void
*/
public function upsertMarketScanWaypoint(
string $systemSymbol,
string $waypointSymbol,
array $exports,
string $probeShipSymbol = '',
string $errorMessage = ''
): void {
$exportsJson = json_encode( array_values( $exports ) );
if ($exportsJson === false ) {
return;
}
$stmt = $this->db->prepare(
'INSERT INTO market_scan_waypoints (
system_symbol,
waypoint_symbol,
exports_json,
probe_ship_symbol,
error_message,
updated_at
)
VALUES (
:system_symbol,
:waypoint_symbol,
:exports_json,
:probe_ship_symbol,
:error_message,
:updated_at
)
ON CONFLICT(system_symbol, waypoint_symbol) DO UPDATE SET
exports_json = excluded.exports_json,
probe_ship_symbol = excluded.probe_ship_symbol,
error_message = excluded.error_message,
updated_at = excluded.updated_at'
);
$stmt->execute(
array(
':system_symbol' => $systemSymbol,
':waypoint_symbol' => $waypointSymbol,
':exports_json' => $exportsJson,
':probe_ship_symbol' => $probeShipSymbol,
':error_message' => $errorMessage,
':updated_at' => time(),
)
);
}
/**
* Load scanned market export data for a system.
*
* @param string $systemSymbol System symbol.
*
* @return array<int,array<string,mixed>>
*/
public function getMarketScanWaypointsBySystem( string $systemSymbol ): array {
$stmt = $this->db->prepare(
'SELECT
system_symbol,
waypoint_symbol,
exports_json,
probe_ship_symbol,
error_message,
updated_at
FROM market_scan_waypoints
WHERE system_symbol = :system_symbol
ORDER BY waypoint_symbol ASC'
);
$stmt->execute( array( ':system_symbol' => $systemSymbol ) );
$rows = $stmt->fetchAll();
if (! is_array( $rows ) ) {
return array();
}
foreach ( $rows as &$row ) {
$decodedExports = json_decode( (string) ( $row['exports_json'] ?? '[]' ), true );
$row['exports'] = is_array( $decodedExports ) ? $decodedExports : array();
}
unset( $row );
return $rows;
}
}