From 9b6f1536a2c8dfd783218de4bd754b2bec73c7fc Mon Sep 17 00:00:00 2001 From: Eric Seidel Date: Sun, 18 Feb 2024 14:37:46 -0800 Subject: [PATCH] feat: move ShipyardListing into the db I'd done most of the work before but hadn't finished. --- packages/cli/bin/asteroids.dart | 4 +- packages/cli/bin/contracts.dart | 2 +- packages/cli/bin/shipyard_prices.dart | 2 +- packages/cli/bin/system_routing.dart | 2 +- packages/cli/bin/system_stats.dart | 4 +- packages/cli/bin/systems_explored.dart | 2 +- packages/cli/lib/cache/caches.dart | 8 +-- .../cli/lib/cache/shipyard_listing_cache.dart | 69 +++++-------------- packages/cli/lib/cache/shipyard_prices.dart | 8 ++- packages/cli/lib/idle_queue.dart | 2 +- packages/cli/lib/net/direct.dart | 2 +- packages/cli/test/cache/caches_mock.dart | 3 +- .../cache/shipyard_listing_cache_test.dart | 30 -------- 13 files changed, 39 insertions(+), 99 deletions(-) delete mode 100644 packages/cli/test/cache/shipyard_listing_cache_test.dart diff --git a/packages/cli/bin/asteroids.dart b/packages/cli/bin/asteroids.dart index 0b12cdf0..669350b6 100644 --- a/packages/cli/bin/asteroids.dart +++ b/packages/cli/bin/asteroids.dart @@ -5,7 +5,7 @@ Future command(FileSystem fs, ArgResults argResults) async { final db = await defaultDatabase(); // List all known asteroids that have a market or shipyard. final marketListings = await MarketListingSnapshot.load(db); - final shipyardListingCache = ShipyardListingCache.load(fs); + final shipyardListings = await ShipyardListingSnapshot.load(db); final systemsCache = SystemsCache.load(fs)!; for (final marketListing in marketListings.listings) { @@ -14,7 +14,7 @@ Future command(FileSystem fs, ArgResults argResults) async { if (!waypoint.isAsteroid) { continue; } - final shipyardListing = shipyardListingCache[waypointSymbol]; + final shipyardListing = shipyardListings[waypointSymbol]; if (shipyardListing != null) { logger.info('Asteroid $waypointSymbol has a market and shipyard.'); } else { diff --git a/packages/cli/bin/contracts.dart b/packages/cli/bin/contracts.dart index ae6aac97..8b431364 100644 --- a/packages/cli/bin/contracts.dart +++ b/packages/cli/bin/contracts.dart @@ -1,5 +1,5 @@ import 'package:cli/behavior/trader.dart'; -import 'package:cli/cache/contract_cache.dart'; +import 'package:cli/cache/contract_snapshot.dart'; import 'package:cli/cache/market_prices.dart'; import 'package:cli/cli.dart'; import 'package:cli/printing.dart'; diff --git a/packages/cli/bin/shipyard_prices.dart b/packages/cli/bin/shipyard_prices.dart index 00eaf30d..e0c76e73 100644 --- a/packages/cli/bin/shipyard_prices.dart +++ b/packages/cli/bin/shipyard_prices.dart @@ -14,7 +14,7 @@ Future command(FileSystem fs, ArgResults argResults) async { 'Loaded ${shipyardPrices.count} prices from ' '${shipyardPrices.waypointCount} waypoints.', ); - final shipyardListings = ShipyardListingCache.load(fs); + final shipyardListings = await ShipyardListingSnapshot.load(db); logger.info( 'Loaded ${shipyardListings.count} listings from ' '${shipyardListings.waypointCount} waypoints.', diff --git a/packages/cli/bin/system_routing.dart b/packages/cli/bin/system_routing.dart index 00ccf20b..82d6ca55 100644 --- a/packages/cli/bin/system_routing.dart +++ b/packages/cli/bin/system_routing.dart @@ -14,7 +14,7 @@ Future command(FileSystem fs, ArgResults argResults) async { final systems = SystemsCache.load(fs)!; final hqSystemSymbol = await myHqSystemSymbol(db); final marketListings = await MarketListingSnapshot.load(db); - final shipyardListings = ShipyardListingCache.load(fs); + final shipyardListings = await ShipyardListingSnapshot.load(db); final systemConnectivity = await loadSystemConnectivity(db); final routePlanner = RoutePlanner.fromSystemsCache( systems, diff --git a/packages/cli/bin/system_stats.dart b/packages/cli/bin/system_stats.dart index 5e930d2e..74d4fa3d 100644 --- a/packages/cli/bin/system_stats.dart +++ b/packages/cli/bin/system_stats.dart @@ -78,9 +78,9 @@ Future command(FileSystem fs, ArgResults argResults) async { logger.info('$markets markets'); // How many shipyards? - final shipyardListingCache = ShipyardListingCache.load(fs); + final shipyardListings = await ShipyardListingSnapshot.load(db); var shipyards = 0; - for (final listing in shipyardListingCache.listings) { + for (final listing in shipyardListings.listings) { // We could sort first by system to save ourselves some lookups. final systemSymbol = listing.waypointSymbol.system; if (reachableSystems.contains(systemSymbol)) { diff --git a/packages/cli/bin/systems_explored.dart b/packages/cli/bin/systems_explored.dart index d297d548..cc0efab9 100644 --- a/packages/cli/bin/systems_explored.dart +++ b/packages/cli/bin/systems_explored.dart @@ -17,7 +17,7 @@ Future command(FileSystem fs, ArgResults argResults) async { final chartingSnapshot = await ChartingSnapshot.load(db); final systemsCache = SystemsCache.load(fs)!; final marketListings = await MarketListingSnapshot.load(db); - final shipyardListings = ShipyardListingCache.load(fs); + final shipyardListings = await ShipyardListingSnapshot.load(db); // Having market data means it's charted (either by us or someone else). // final systemsWithMarketPrices = diff --git a/packages/cli/lib/cache/caches.dart b/packages/cli/lib/cache/caches.dart index 26b723a0..6e5b20db 100644 --- a/packages/cli/lib/cache/caches.dart +++ b/packages/cli/lib/cache/caches.dart @@ -3,7 +3,7 @@ import 'package:cli/cache/agent_cache.dart'; import 'package:cli/cache/behavior_cache.dart'; import 'package:cli/cache/charting_cache.dart'; import 'package:cli/cache/construction_cache.dart'; -import 'package:cli/cache/contract_cache.dart'; +import 'package:cli/cache/contract_snapshot.dart'; import 'package:cli/cache/jump_gate_cache.dart'; import 'package:cli/cache/market_cache.dart'; import 'package:cli/cache/market_prices.dart'; @@ -28,7 +28,7 @@ export 'package:cli/cache/agent_cache.dart'; export 'package:cli/cache/behavior_cache.dart'; export 'package:cli/cache/charting_cache.dart'; export 'package:cli/cache/construction_cache.dart'; -export 'package:cli/cache/contract_cache.dart'; +export 'package:cli/cache/contract_snapshot.dart'; export 'package:cli/cache/jump_gate_cache.dart'; export 'package:cli/cache/market_cache.dart'; export 'package:cli/cache/market_prices.dart'; @@ -81,7 +81,7 @@ class Caches { ContractSnapshot contracts; /// Known shipyard listings. - final ShipyardListingCache shipyardListings; + final ShipyardListingSnapshot shipyardListings; /// The historical shipyard prices. final ShipyardPrices shipyardPrices; @@ -136,7 +136,7 @@ class Caches { final ships = await ShipCache.loadOrFetch(api, fs: fs, forceRefresh: true); final marketPrices = await MarketPrices.load(db); final shipyardPrices = await ShipyardPrices.load(db); - final shipyardListings = ShipyardListingCache.load(fs); + final shipyardListings = await ShipyardListingSnapshot.load(db); final systems = await SystemsCache.loadOrFetch(fs, httpGet: httpGet); final static = StaticCaches.load(fs); final charting = ChartingCache(db); diff --git a/packages/cli/lib/cache/shipyard_listing_cache.dart b/packages/cli/lib/cache/shipyard_listing_cache.dart index 942ab21c..473c37c7 100644 --- a/packages/cli/lib/cache/shipyard_listing_cache.dart +++ b/packages/cli/lib/cache/shipyard_listing_cache.dart @@ -1,53 +1,21 @@ -import 'package:cli/cache/caches.dart'; -import 'package:cli/cache/json_store.dart'; +import 'package:db/db.dart'; import 'package:types/types.dart'; -typedef _Record = Map; - /// A cached of charted values from Waypoints. -class ShipyardListingCache extends JsonStore<_Record> { +class ShipyardListingSnapshot { /// Creates a new charting cache. - ShipyardListingCache( - super.entries, { - required super.fs, - super.path = defaultPath, - }) : super( - recordToJson: (_Record r) => r.map( - (key, value) => MapEntry( - key.toJson(), - value.toJson(), - ), - ), - ); + ShipyardListingSnapshot(Iterable listings) + : _listingBySymbol = + Map.fromEntries(listings.map((l) => MapEntry(l.waypointSymbol, l))); /// Load the charted values from the cache. - factory ShipyardListingCache.load( - FileSystem fs, { - String path = defaultPath, - }) { - final valuesBySymbol = JsonStore.loadRecord<_Record>( - fs, - path, - (Map j) => j.map( - (key, value) => MapEntry( - WaypointSymbol.fromJson(key), - ShipyardListing.fromJson(value as Map), - ), - ), - ) ?? - {}; - return ShipyardListingCache( - valuesBySymbol, - fs: fs, - path: path, - ); + static Future load(Database db) async { + final values = await db.allShipyardListings(); + return ShipyardListingSnapshot(values); } - /// The default path to the cache file. - static const defaultPath = 'data/shipyard_listings.json'; - /// The ShipyardListings by WaypointSymbol. - Map get _listingBySymbol => record; + final Map _listingBySymbol; /// The ShipyardListings. Iterable get listings => _listingBySymbol.values; @@ -75,15 +43,14 @@ class ShipyardListingCache extends JsonStore<_Record> { /// Fetch the ShipyardListing for the given WaypointSymbol. ShipyardListing? operator [](WaypointSymbol waypointSymbol) => listingForSymbol(waypointSymbol); +} - /// Add ShipyardListing for the given Shipyard to the cache. - void addShipyard(Shipyard shipyard) { - final symbol = shipyard.waypointSymbol; - final listing = ShipyardListing( - waypointSymbol: symbol, - shipTypes: shipyard.shipTypes.map((inner) => inner.type).toSet(), - ); - _listingBySymbol[symbol] = listing; - save(); - } +/// Add ShipyardListing for the given Shipyard to the cache. +void recordShipyardListing(Database db, Shipyard shipyard) { + final symbol = shipyard.waypointSymbol; + final listing = ShipyardListing( + waypointSymbol: symbol, + shipTypes: shipyard.shipTypes.map((inner) => inner.type).toSet(), + ); + db.upsertShipyardListing(listing); } diff --git a/packages/cli/lib/cache/shipyard_prices.dart b/packages/cli/lib/cache/shipyard_prices.dart index 341703a0..4987c41f 100644 --- a/packages/cli/lib/cache/shipyard_prices.dart +++ b/packages/cli/lib/cache/shipyard_prices.dart @@ -1,6 +1,7 @@ import 'dart:math'; import 'package:cli/cache/prices_cache.dart'; +import 'package:cli/cache/shipyard_listing_cache.dart'; import 'package:cli/cache/static_cache.dart'; import 'package:cli/config.dart'; import 'package:cli/logger.dart'; @@ -99,14 +100,15 @@ void recordShipyardDataAndLog( Shipyard shipyard, Ship ship, ) { - recordShipyardData(db, shipyard); + recordShipyardPrices(db, shipyard); recordShipyardShips(staticCaches, shipyard.ships); + recordShipyardListing(db, shipyard); // Powershell needs an extra space after the emoji. shipInfo(ship, '✍️ shipyard data @ ${shipyard.symbol}'); } -/// Record shipyard data. -void recordShipyardData( +/// Record shipyard prices. +void recordShipyardPrices( Database db, Shipyard shipyard, { DateTime Function() getNow = defaultGetNow, diff --git a/packages/cli/lib/idle_queue.dart b/packages/cli/lib/idle_queue.dart index 122a36c1..17ca36bb 100644 --- a/packages/cli/lib/idle_queue.dart +++ b/packages/cli/lib/idle_queue.dart @@ -142,7 +142,7 @@ class IdleQueue { if (listing == null) { logger.info(' Shipyard: $waypointSymbol'); final shipyard = await getShipyard(api, waypointSymbol); - caches.shipyardListings.addShipyard(shipyard); + recordShipyardListing(db, shipyard); } } diff --git a/packages/cli/lib/net/direct.dart b/packages/cli/lib/net/direct.dart index a13a2654..d4da751b 100644 --- a/packages/cli/lib/net/direct.dart +++ b/packages/cli/lib/net/direct.dart @@ -1,7 +1,7 @@ import 'package:cli/api.dart'; import 'package:cli/cache/agent_cache.dart'; import 'package:cli/cache/construction_cache.dart'; -import 'package:cli/cache/contract_cache.dart'; +import 'package:cli/cache/contract_snapshot.dart'; import 'package:cli/cache/ship_cache.dart'; import 'package:db/db.dart'; import 'package:types/types.dart'; diff --git a/packages/cli/test/cache/caches_mock.dart b/packages/cli/test/cache/caches_mock.dart index e364a644..f4ca1bfb 100644 --- a/packages/cli/test/cache/caches_mock.dart +++ b/packages/cli/test/cache/caches_mock.dart @@ -32,7 +32,8 @@ class _MockShipMountCache extends Mock implements ShipMountCache {} class _MockShipReactorCache extends Mock implements ShipReactorCache {} -class _MockShipyardListingCache extends Mock implements ShipyardListingCache {} +class _MockShipyardListingCache extends Mock + implements ShipyardListingSnapshot {} class _MockShipyardPrices extends Mock implements ShipyardPrices {} diff --git a/packages/cli/test/cache/shipyard_listing_cache_test.dart b/packages/cli/test/cache/shipyard_listing_cache_test.dart deleted file mode 100644 index 9fc57364..00000000 --- a/packages/cli/test/cache/shipyard_listing_cache_test.dart +++ /dev/null @@ -1,30 +0,0 @@ -import 'package:cli/cache/shipyard_listing_cache.dart'; -import 'package:file/memory.dart'; -import 'package:test/test.dart'; -import 'package:types/types.dart'; - -void main() { - test('ShipyardListingCache load/save', () async { - final fs = MemoryFileSystem.test(); - final waypointSymbol = WaypointSymbol.fromString('W-A-Y'); - final listing = ShipyardListing( - waypointSymbol: waypointSymbol, - shipTypes: const {ShipType.INTERCEPTOR}, - ); - ShipyardListingCache({waypointSymbol: listing}, fs: fs).save(); - final loaded = ShipyardListingCache.load(fs); - expect(loaded[waypointSymbol], listing); - - final newSymbol = WaypointSymbol.fromString('T-W-O'); - final shipyard = Shipyard( - symbol: newSymbol.waypoint, - shipTypes: [ - ShipyardShipTypesInner(type: ShipType.EXPLORER), - ], - modificationsFee: 100, - ); - loaded.addShipyard(shipyard); - expect(loaded[newSymbol], isNotNull); - expect(loaded[newSymbol]!.shipTypes, {ShipType.EXPLORER}); - }); -}