From 84392b4679ba91eb84f3e2f5feadcdabc6379bbd Mon Sep 17 00:00:00 2001 From: Eric Seidel Date: Sat, 12 Aug 2023 20:12:33 -0700 Subject: [PATCH] feat: Move factions to the database This removes the FactionCache. I also converted varchar to text and json types in the db. Renamed toSubsitutionValues to toColumnMap to be shorter and easier to spell. removed factionCache from ui for now. --- README.md | 7 +- packages/cli/bin/cli.dart | 2 +- packages/cli/bin/route_perf.dart | 7 +- .../bin/systems_reachable_from_factions.dart | 11 +-- packages/cli/lib/behavior/explorer.dart | 18 ++-- packages/cli/lib/cache/caches.dart | 42 ++++++--- packages/cli/lib/cache/faction_cache.dart | 90 ------------------- packages/cli/lib/net/queue.dart | 4 +- packages/cli/test/cache/caches_test.dart | 18 ++-- .../cli/test/cache/faction_cache_test.dart | 30 ------- packages/db/lib/db.dart | 30 +++++++ packages/db/lib/faction.dart | 36 ++++++++ packages/db/lib/survey.dart | 14 +-- packages/db/lib/transaction.dart | 4 +- packages/db/scripts/init_db.sh | 3 +- packages/db/sql/flows/drop_tables.sql | 3 +- packages/db/sql/tables/01_request.sql | 2 +- packages/db/sql/tables/02_response.sql | 2 +- packages/db/sql/tables/03_transaction.sql | 14 +-- packages/db/sql/tables/04_survey.sql | 11 ++- packages/db/sql/tables/05_faction.sql | 7 ++ packages/ui/lib/main.dart | 7 -- packages/ui/lib/map.dart | 6 -- 23 files changed, 168 insertions(+), 200 deletions(-) delete mode 100644 packages/cli/lib/cache/faction_cache.dart delete mode 100644 packages/cli/test/cache/faction_cache_test.dart create mode 100644 packages/db/lib/faction.dart create mode 100644 packages/db/sql/tables/05_faction.sql diff --git a/README.md b/README.md index 88aa9cbb..b4d3ddd8 100644 --- a/README.md +++ b/README.md @@ -641,4 +641,9 @@ Invalid argument (marketSymbol): ESEIDEL-6F is not at X1-YA22-87615D, X1-YA22-92 ### Types Move Transaction and other custom model objects down to that layer. -Remove api.dart re-export of types. \ No newline at end of file +Remove api.dart re-export of types. + +### Surveys +Miners will likely fight over surveys, probably all grabbing the "best" +survey and possibly exhausting it at the same time and having to restart +the mining operation? \ No newline at end of file diff --git a/packages/cli/bin/cli.dart b/packages/cli/bin/cli.dart index edd059fa..90e14396 100644 --- a/packages/cli/bin/cli.dart +++ b/packages/cli/bin/cli.dart @@ -93,7 +93,7 @@ Future cliMain(List args) async { final api = getApi(token, db, useOutOfProcessNetwork: !(results['local'] as bool)); - final caches = await Caches.load(fs, api); + final caches = await Caches.load(fs, api, db); logger.info( 'Loaded ${caches.marketPrices.count} prices from ' '${caches.marketPrices.waypointCount} markets and ' diff --git a/packages/cli/bin/route_perf.dart b/packages/cli/bin/route_perf.dart index 3f50e749..cde733a7 100644 --- a/packages/cli/bin/route_perf.dart +++ b/packages/cli/bin/route_perf.dart @@ -1,10 +1,10 @@ import 'package:cli/api.dart'; -import 'package:cli/cache/faction_cache.dart'; import 'package:cli/cache/systems_cache.dart'; import 'package:cli/cli.dart'; import 'package:cli/nav/jump_cache.dart'; import 'package:cli/nav/route.dart'; import 'package:cli/nav/system_connectivity.dart'; +import 'package:db/db.dart'; void main(List args) async { await runOffline(args, command); @@ -25,12 +25,13 @@ class Result { Future command(FileSystem fs, List args) async { const count = 5000; + final db = await defaultDatabase(); final systemsCache = SystemsCache.loadCached(fs)!; final systemConnectivity = SystemConnectivity.fromSystemsCache(systemsCache); final jumpCache = JumpCache(); - final factionCache = FactionCache.loadFromCache(fs)!; // COSMIC has always been on the main jumpgate network. - final factionHq = factionCache.headquartersFor(FactionSymbols.COSMIC); + final factionHq = + (await db.factionBySymbol(FactionSymbols.COSMIC)).headquartersSymbol; final systemSymbol = factionHq.systemSymbol; final clusterId = systemConnectivity.clusterIdForSystem(systemSymbol); final allSystemSymbols = diff --git a/packages/cli/bin/systems_reachable_from_factions.dart b/packages/cli/bin/systems_reachable_from_factions.dart index b9a81ee2..c17eac32 100644 --- a/packages/cli/bin/systems_reachable_from_factions.dart +++ b/packages/cli/bin/systems_reachable_from_factions.dart @@ -1,14 +1,11 @@ -import 'package:cli/api.dart'; -import 'package:cli/cache/faction_cache.dart'; -import 'package:cli/cache/systems_cache.dart'; +import 'package:cli/cache/caches.dart'; import 'package:cli/cli.dart'; -import 'package:cli/nav/system_connectivity.dart'; +import 'package:db/db.dart'; Future command(FileSystem fs, List args) async { + final db = await defaultDatabase(); final systemsCache = await SystemsCache.load(fs); - final factionCache = await FactionCache.loadUnauthenticated(fs); - - final factions = factionCache.factions; + final factions = await loadFactions(db); final clusterCache = SystemConnectivity.fromSystemsCache(systemsCache); for (final faction in factions) { diff --git a/packages/cli/lib/behavior/explorer.dart b/packages/cli/lib/behavior/explorer.dart index b77c12c1..2e215fdc 100644 --- a/packages/cli/lib/behavior/explorer.dart +++ b/packages/cli/lib/behavior/explorer.dart @@ -185,17 +185,17 @@ Future findNewWaypointSymbolToExplore( return null; } -WaypointSymbol _nearestHeadquarters( +Future _nearestHeadquarters( + Database db, SystemConnectivity systemConnectivity, SystemsCache systemsCache, AgentCache agentCache, - FactionCache factionCache, Ship ship, -) { - final factionsHqs = - factionCache.factions.map((e) => e.headquartersSymbol).toList(); +) async { + final factionHqs = + (await loadFactions(db)).map((e) => e.headquartersSymbol).toList(); final startSystem = systemsCache.systemBySymbol(ship.systemSymbol); - final reachableHqs = factionsHqs + final reachableHqs = factionHqs .where( (hq) => systemConnectivity.canJumpBetweenSystemSymbols( ship.systemSymbol, @@ -217,6 +217,7 @@ WaypointSymbol _nearestHeadquarters( /// If we're low on fuel, route to the nearest market which trades fuel. Future routeForEmergencyFuelingIfNeeded( Api api, + Database db, Caches caches, CentralCommand centralCommand, Waypoint waypoint, @@ -237,11 +238,11 @@ Future routeForEmergencyFuelingIfNeeded( ?.waypointSymbol; if (destination == null) { shipErr(ship, 'No nearby market trades fuel, routing to nearest hq.'); - destination = _nearestHeadquarters( + destination = await _nearestHeadquarters( + db, caches.systemConnectivity, caches.systems, caches.agent, - caches.factions, ship, ); } @@ -307,6 +308,7 @@ Future advanceExplorer( // which do not have markets. Other behaviors always stick to markets. final refuelWaitTime = await routeForEmergencyFuelingIfNeeded( api, + db, caches, centralCommand, waypoint, diff --git a/packages/cli/lib/cache/caches.dart b/packages/cli/lib/cache/caches.dart index 07910ac7..2cd6602e 100644 --- a/packages/cli/lib/cache/caches.dart +++ b/packages/cli/lib/cache/caches.dart @@ -4,7 +4,6 @@ import 'package:cli/cache/behavior_cache.dart'; import 'package:cli/cache/charting_cache.dart'; import 'package:cli/cache/contract_cache.dart'; import 'package:cli/cache/extraction_log.dart'; -import 'package:cli/cache/faction_cache.dart'; import 'package:cli/cache/market_prices.dart'; import 'package:cli/cache/ship_cache.dart'; import 'package:cli/cache/shipyard_prices.dart'; @@ -13,6 +12,8 @@ import 'package:cli/cache/waypoint_cache.dart'; import 'package:cli/nav/jump_cache.dart'; import 'package:cli/nav/route.dart'; import 'package:cli/nav/system_connectivity.dart'; +import 'package:cli/net/queries.dart'; +import 'package:db/db.dart'; import 'package:file/file.dart'; import 'package:http/http.dart' as http; @@ -22,7 +23,6 @@ export 'package:cli/cache/behavior_cache.dart'; export 'package:cli/cache/charting_cache.dart'; export 'package:cli/cache/contract_cache.dart'; export 'package:cli/cache/extraction_log.dart'; -export 'package:cli/cache/faction_cache.dart'; export 'package:cli/cache/market_prices.dart'; export 'package:cli/cache/ship_cache.dart'; export 'package:cli/cache/shipyard_prices.dart'; @@ -47,7 +47,6 @@ class Caches { required this.markets, required this.contracts, required this.behaviors, - required this.factions, required this.charting, required this.routePlanner, }); @@ -85,9 +84,6 @@ class Caches { /// The cache of behaviors. final BehaviorCache behaviors; - /// The cache of factions. - final FactionCache factions; - /// The cache of charting data. final ChartingCache charting; @@ -97,7 +93,8 @@ class Caches { /// Load the cache from disk and network. static Future load( FileSystem fs, - Api api, { + Api api, + Database db, { Future Function(Uri uri) httpGet = defaultHttpGet, }) async { final agent = await AgentCache.load(api, fs: fs); @@ -113,8 +110,6 @@ class Caches { // Intentionally force refresh contracts in case we've been offline. final contracts = await ContractCache.load(api, fs: fs, forceRefresh: true); final behaviors = BehaviorCache.load(fs); - // Intentionally load factions from disk (they never change). - final factions = await FactionCache.load(api, fs: fs); final systemConnectivity = SystemConnectivity.fromSystemsCache(systems); final jumps = JumpCache(); @@ -124,8 +119,8 @@ class Caches { systemConnectivity: systemConnectivity, ); - // Save out the caches we never modify so we don't have to load them again. - factions.save(); + // Make sure factions are loaded. + await loadFactions(db); // We rarely modify contracts, so save them out here too. contracts.save(); @@ -142,7 +137,6 @@ class Caches { markets: markets, contracts: contracts, behaviors: behaviors, - factions: factions, charting: charting, routePlanner: routePlanner, ); @@ -169,3 +163,27 @@ class Caches { ships.save(); } } + +/// Load all factions from the API. +// With our out-of-process rate limiting, this won't matter that it uses +// a separate API client. +Future> allFactionsUnauthenticated() async { + final factionsApi = FactionsApi(); + final factions = await fetchAllPages(factionsApi, (factionsApi, page) async { + final response = await factionsApi.getFactions(page: page); + return (response!.data, response.meta); + }).toList(); + return factions; +} + +/// Loads the factions from the database, or fetches them from the API if +/// they're not cached. +Future> loadFactions(Database db) async { + final cachedFactions = await db.allFactions(); + if (cachedFactions.isNotEmpty) { + return Future.value(cachedFactions); + } + final factions = await allFactionsUnauthenticated(); + await db.cacheFactions(factions); + return factions; +} diff --git a/packages/cli/lib/cache/faction_cache.dart b/packages/cli/lib/cache/faction_cache.dart deleted file mode 100644 index 0ebcd53a..00000000 --- a/packages/cli/lib/cache/faction_cache.dart +++ /dev/null @@ -1,90 +0,0 @@ -import 'package:cli/api.dart'; -import 'package:cli/cache/json_list_store.dart'; -import 'package:cli/cache/response_cache.dart'; -import 'package:cli/net/queries.dart'; -import 'package:file/file.dart'; - -/// On disk cache of factions. -class FactionCache extends ResponseListCache { - /// Creates a new faction cache. - FactionCache( - super.factions, { - required super.fs, // Factions should never change. - super.checkEvery = 10000, - super.path = defaultPath, - }) : super( - entryToJson: (c) => c.toJson(), - refreshEntries: (Api api) => getAllFactions(api).toList(), - ); - - /// Creates a new FactionCache from the cache if possible. - static FactionCache? loadFromCache( - FileSystem fs, { - String path = defaultPath, - }) { - final factions = JsonListStore.load( - fs, - path, - (j) => Faction.fromJson(j)!, - ); - if (factions == null) { - return null; - } - return FactionCache(factions, fs: fs, path: path); - } - - /// Creates a new FactionCache using an unauthenticated Api. - static Future loadUnauthenticated( - FileSystem fs, { - String path = defaultPath, - }) async { - final cached = loadFromCache(fs); - if (cached != null) { - return cached; - } - final factionsApi = FactionsApi(); - final factions = - await fetchAllPages(factionsApi, (factionsApi, page) async { - final response = await factionsApi.getFactions(page: page); - return (response!.data, response.meta); - }).toList(); - return FactionCache(factions, fs: fs, path: path); - } - - /// Creates a new FactionCache from the Api or FileSystem if provided. - static Future load( - Api api, { - required FileSystem fs, - String path = defaultPath, - bool forceRefresh = false, - }) async { - if (!forceRefresh && await fs.isFile(path)) { - final factions = JsonListStore.load( - fs, - path, - (j) => Faction.fromJson(j)!, - ); - if (factions != null) { - return FactionCache(factions, fs: fs, path: path); - } - } - final factions = await getAllFactions(api).toList(); - return FactionCache(factions, fs: fs, path: path); - } - - /// The default path to the factions cache. - static const String defaultPath = 'data/factions.json'; - - /// Factions in the cache. - List get factions => entries; - - /// Gets the faction with the given symbol. - Faction factionBySymbol(FactionSymbols symbol) => - factions.firstWhere((f) => f.symbol == symbol); - - /// Gets the headquarters for the given faction. - WaypointSymbol headquartersFor(FactionSymbols symbol) { - final faction = factionBySymbol(symbol); - return WaypointSymbol.fromString(faction.headquarters); - } -} diff --git a/packages/cli/lib/net/queue.dart b/packages/cli/lib/net/queue.dart index 2d4d24c6..55fca9d3 100644 --- a/packages/cli/lib/net/queue.dart +++ b/packages/cli/lib/net/queue.dart @@ -271,7 +271,7 @@ class NetQueue { continue; } final queued = QueuedResponse.fromJson( - jsonDecode(result[0][0] as String) as Map, + result[0][0] as Map, ); return queued.toResponse(); } @@ -299,7 +299,7 @@ class NetQueue { id: row[0] as int, priority: row[1] as int, request: QueuedRequest.fromJson( - jsonDecode(row[2] as String) as Map, + row[2] as Map, ), ); } diff --git a/packages/cli/test/cache/caches_test.dart b/packages/cli/test/cache/caches_test.dart index 7bc04566..9792f572 100644 --- a/packages/cli/test/cache/caches_test.dart +++ b/packages/cli/test/cache/caches_test.dart @@ -1,26 +1,30 @@ import 'package:cli/cache/caches.dart'; import 'package:cli/logger.dart'; +import 'package:db/db.dart'; import 'package:file/memory.dart'; import 'package:mocktail/mocktail.dart'; import 'package:test/test.dart'; -class _MockApi extends Mock implements Api {} - -class _MockAgentsApi extends Mock implements AgentsApi {} - class _MockAgent extends Mock implements Agent {} -class _MockFleetApi extends Mock implements FleetApi {} +class _MockAgentsApi extends Mock implements AgentsApi {} -class _MockLogger extends Mock implements Logger {} +class _MockApi extends Mock implements Api {} class _MockContractsApi extends Mock implements ContractsApi {} +class _MockDatabase extends Mock implements Database {} + class _MockFactionsApi extends Mock implements FactionsApi {} +class _MockFleetApi extends Mock implements FleetApi {} + +class _MockLogger extends Mock implements Logger {} + void main() { test('Caches load test', () async { final api = _MockApi(); + final db = _MockDatabase(); final agentsApi = _MockAgentsApi(); when(() => api.agents).thenReturn(agentsApi); final agent = _MockAgent(); @@ -69,7 +73,7 @@ void main() { Never httpGet(f) => throw UnimplementedError(); final caches = await runWithLogger( logger, - () async => Caches.load(fs, api, httpGet: httpGet), + () async => Caches.load(fs, api, db, httpGet: httpGet), ); expect(caches.agent, isNotNull); }); diff --git a/packages/cli/test/cache/faction_cache_test.dart b/packages/cli/test/cache/faction_cache_test.dart deleted file mode 100644 index fde45aaf..00000000 --- a/packages/cli/test/cache/faction_cache_test.dart +++ /dev/null @@ -1,30 +0,0 @@ -import 'package:cli/api.dart'; -import 'package:cli/cache/faction_cache.dart'; -import 'package:file/memory.dart'; -import 'package:test/test.dart'; - -void main() { - test('FactionCache load/save', () async { - final fs = MemoryFileSystem.test(); - final cache = FactionCache( - [ - Faction( - symbol: FactionSymbols.AEGIS, - name: 'A', - description: 'description', - headquarters: 'S-A-W', - isRecruiting: true, - ) - ], - fs: fs, - ); - expect(cache.factions.length, 1); - cache.save(); - final cache2 = FactionCache.loadFromCache(fs)!; - expect(cache2.factions.length, 1); - final faction = cache2.factionBySymbol(FactionSymbols.AEGIS); - expect(faction.isRecruiting, isTrue); - final hq = cache2.headquartersFor(FactionSymbols.AEGIS); - expect(hq.waypoint, 'S-A-W'); - }); -} diff --git a/packages/db/lib/db.dart b/packages/db/lib/db.dart index 3441eab3..158c46d4 100644 --- a/packages/db/lib/db.dart +++ b/packages/db/lib/db.dart @@ -1,3 +1,4 @@ +import 'package:db/faction.dart'; import 'package:db/survey.dart'; import 'package:db/transaction.dart'; import 'package:postgres/postgres.dart'; @@ -84,4 +85,33 @@ class Database { throw ArgumentError('Survey not found: $survey'); } } + + /// Gets the faction with the given symbol. + Future factionBySymbol(FactionSymbols symbol) { + final query = factionBySymbolQuery(symbol); + return connection + .query(query.fmtString, substitutionValues: query.substitutionValues) + .then((result) => factionFromResultRow(result.first)); + } + + /// Gets all factions. + Future> allFactions() { + final query = allFactionsQuery(); + return connection + .query(query.fmtString, substitutionValues: query.substitutionValues) + .then((result) => result.map(factionFromResultRow).toList()); + } + + /// Cache the given factions. + Future cacheFactions(List factions) async { + await connection.transaction((connection) async { + for (final faction in factions) { + final query = insertFactionQuery(faction); + await connection.query( + query.fmtString, + substitutionValues: query.substitutionValues, + ); + } + }); + } } diff --git a/packages/db/lib/faction.dart b/packages/db/lib/faction.dart new file mode 100644 index 00000000..dbbfbdb9 --- /dev/null +++ b/packages/db/lib/faction.dart @@ -0,0 +1,36 @@ +import 'package:db/query.dart'; +import 'package:postgres/postgres.dart'; +import 'package:types/types.dart'; + +/// Query all factions. +Query allFactionsQuery() => const Query( + 'SELECT * FROM faction_', + substitutionValues: {}, + ); + +/// Query a faction by symbol. +Query factionBySymbolQuery(FactionSymbols symbol) => Query( + 'SELECT * FROM faction_ WHERE symbol = @symbol', + substitutionValues: { + 'symbol': symbol.toString(), + }, + ); + +/// insert a faction. +Query insertFactionQuery(Faction faction) => Query( + 'INSERT INTO faction_ (symbol, json) ' + 'VALUES (@symbol, @json)', + substitutionValues: factionToColumnMap(faction), + ); + +/// Convert a faction to a column map. +Map factionToColumnMap(Faction faction) => { + 'symbol': faction.symbol.toString(), + 'json': faction.toJson(), + }; + +/// Convert a result row to a faction. +Faction factionFromResultRow(PostgreSQLResultRow row) { + final values = row.toColumnMap(); + return Faction.fromJson(values['json'] as Map)!; +} diff --git a/packages/db/lib/survey.dart b/packages/db/lib/survey.dart index b4613c3e..bf80db7b 100644 --- a/packages/db/lib/survey.dart +++ b/packages/db/lib/survey.dart @@ -22,7 +22,7 @@ HistoricalSurvey surveyFromResultRow(PostgreSQLResultRow row) { } /// Convert a survey into substitution values for a query. -Map surveyToSubstitutionValues(HistoricalSurvey survey) { +Map surveyToColumnMap(HistoricalSurvey survey) { return { 'signature': survey.survey.signature, 'waypoint_symbol': survey.survey.symbol, @@ -40,10 +40,10 @@ Query recentSurveysAtWaypointQuery({ required int count, }) { return Query( - 'SELECT * FROM survey WHERE waypointSymbol = @waypointSymbol ' + 'SELECT * FROM survey_ WHERE waypoint_symbol = @waypointSymbol ' 'ORDER BY timestamp DESC LIMIT @count', substitutionValues: { - 'waypointSymbol': waypointSymbol, + 'waypointSymbol': waypointSymbol.toJson(), 'count': count, }, ); @@ -52,10 +52,10 @@ Query recentSurveysAtWaypointQuery({ /// Insert a survey into the database. Query insertSurveyQuery(HistoricalSurvey survey) { return Query( - 'INSERT INTO survey (signature, waypoint_symbol, deposits, expiration, ' - 'size, timestamp, exhausted) VALUES (@signature, @waypointSymbol, ' + 'INSERT INTO survey_ (signature, waypoint_symbol, deposits, expiration, ' + 'size, timestamp, exhausted) VALUES (@signature, @waypoint_symbol, ' '@deposits, @expiration, @size, @timestamp, @exhausted)', - substitutionValues: surveyToSubstitutionValues(survey), + substitutionValues: surveyToColumnMap(survey), ); } @@ -63,7 +63,7 @@ Query insertSurveyQuery(HistoricalSurvey survey) { Query markSurveyExhaustedQuery(Survey survey) { // "signature" is unique to the survey, "symbol" is the waypoint symbol. return Query( - 'UPDATE survey SET exhausted = true WHERE signature = @signature', + 'UPDATE survey_ SET exhausted = true WHERE signature = @signature', substitutionValues: { 'signature': survey.signature, }, diff --git a/packages/db/lib/transaction.dart b/packages/db/lib/transaction.dart index fefbec31..a1db07e2 100644 --- a/packages/db/lib/transaction.dart +++ b/packages/db/lib/transaction.dart @@ -11,12 +11,12 @@ Query insertTransactionQuery(TransactionRecord record) { 'agent_credits, accounting) VALUES (@transaction_type, @ship_symbol, ' '@waypoint_symbol, @trade_symbol, @ship_type, @quantity, @trade_type, ' '@per_unit_price, @timestamp, @agent_credits, @accounting)', - substitutionValues: toSubstitutionValues(record), + substitutionValues: transactionToColumnMap(record), ); } /// Convert the transaction to substitution values for insertion. -Map toSubstitutionValues(TransactionRecord record) { +Map transactionToColumnMap(TransactionRecord record) { return { 'transaction_type': record.transactionType, 'ship_symbol': record.shipSymbol, diff --git a/packages/db/scripts/init_db.sh b/packages/db/scripts/init_db.sh index 0235cc90..ef8a32a3 100755 --- a/packages/db/scripts/init_db.sh +++ b/packages/db/scripts/init_db.sh @@ -20,4 +20,5 @@ psql -U postgres -d $DB_NAME -f sql/flows/drop_tables.sql psql -U postgres -d $DB_NAME -f sql/tables/01_request.sql psql -U postgres -d $DB_NAME -f sql/tables/02_response.sql psql -U postgres -d $DB_NAME -f sql/tables/03_transaction.sql -psql -U postgres -d $DB_NAME -f sql/tables/04_survey.sql \ No newline at end of file +psql -U postgres -d $DB_NAME -f sql/tables/04_survey.sql +psql -U postgres -d $DB_NAME -f sql/tables/05_faction.sql \ No newline at end of file diff --git a/packages/db/sql/flows/drop_tables.sql b/packages/db/sql/flows/drop_tables.sql index 409e41ac..3c2dd492 100644 --- a/packages/db/sql/flows/drop_tables.sql +++ b/packages/db/sql/flows/drop_tables.sql @@ -1,4 +1,5 @@ DROP TABLE IF EXISTS "request_" CASCADE; DROP TABLE IF EXISTS "response_" CASCADE; DROP TABLE IF EXISTS "transaction_" CASCADE; -DROP TABLE IF EXISTS "survey_" CASCADE; \ No newline at end of file +DROP TABLE IF EXISTS "survey_" CASCADE; +DROP TABLE IF EXISTS "faction_" CASCADE; \ No newline at end of file diff --git a/packages/db/sql/tables/01_request.sql b/packages/db/sql/tables/01_request.sql index 9863feff..f1571cdc 100644 --- a/packages/db/sql/tables/01_request.sql +++ b/packages/db/sql/tables/01_request.sql @@ -5,7 +5,7 @@ CREATE TABLE IF NOT EXISTS "request_" ( -- The priority of the request. "priority" integer NOT NULL, -- The request encoded as json - "json" varchar NOT NULL, + "json" json NOT NULL, -- When the request was created. "created_at" timestamp NULL DEFAULT CURRENT_TIMESTAMP ); \ No newline at end of file diff --git a/packages/db/sql/tables/02_response.sql b/packages/db/sql/tables/02_response.sql index 72072c7f..a9a9e94f 100644 --- a/packages/db/sql/tables/02_response.sql +++ b/packages/db/sql/tables/02_response.sql @@ -5,7 +5,7 @@ CREATE TABLE IF NOT EXISTS "response_" ( -- The unique identifier for the request that caused this response. "request_id" bigserial NOT NULL, -- The response encoded as json - "json" varchar NOT NULL, + "json" json NOT NULL, -- When the response was created. "created_at" timestamp NULL DEFAULT CURRENT_TIMESTAMP ); \ No newline at end of file diff --git a/packages/db/sql/tables/03_transaction.sql b/packages/db/sql/tables/03_transaction.sql index ac6bd7fe..0990a48d 100644 --- a/packages/db/sql/tables/03_transaction.sql +++ b/packages/db/sql/tables/03_transaction.sql @@ -3,21 +3,21 @@ CREATE TABLE IF NOT EXISTS "transaction_" ( -- The unique identifier for the transaction. "id" bigserial NOT NULL PRIMARY KEY, -- The type of transaction. - "transaction_type" varchar(255) NOT NULL, + "transaction_type" text NOT NULL, -- The ship symbol which made the transaction. - "ship_symbol" varchar(255) NOT NULL, + "ship_symbol" text NOT NULL, -- The waypoint symbol where the transaction was made. - "waypoint_symbol" varchar(255) NOT NULL, + "waypoint_symbol" text NOT NULL, -- The trade symbol of the transaction. -- Trade symbol is null for shipyard transactions. - "trade_symbol" varchar(255), + "trade_symbol" text, -- The ship type of the transaction. -- Ship type is null for non-shipyard transactions. - "ship_type" varchar(255), + "ship_type" text, -- The quantity of units transacted. "quantity" int NOT NULL, -- The trade type of the transaction. - "trade_type" varchar(255) NOT NULL, + "trade_type" text NOT NULL, -- The per-unit price of the transaction. "per_unit_price" int NOT NULL, -- The timestamp of the transaction. @@ -25,5 +25,5 @@ CREATE TABLE IF NOT EXISTS "transaction_" ( -- The credits of the agent after the transaction. "agent_credits" int NOT NULL, -- The accounting classification of the transaction. - "accounting" varchar(255) NOT NULL + "accounting" text NOT NULL ); diff --git a/packages/db/sql/tables/04_survey.sql b/packages/db/sql/tables/04_survey.sql index d74cb11b..e8eddb4e 100644 --- a/packages/db/sql/tables/04_survey.sql +++ b/packages/db/sql/tables/04_survey.sql @@ -1,18 +1,17 @@ -- Describes a survey. CREATE TABLE IF NOT EXISTS "survey_" ( -- The unique identifier for the survey. - "signature" varchar(255) NOT NULL PRIMARY KEY, + "signature" text NOT NULL PRIMARY KEY, -- The waypoint symbol where the survey was taken. - "waypoint_symbol" varchar(255) NOT NULL, + "waypoint_symbol" text NOT NULL, -- The deposits found (comma separated trade symbols). - "deposits" varchar(255) NOT NULL, + "deposits" text NOT NULL, -- The expiration time. "expiration" timestamp NOT NULL, -- The size of the survey. SurveySizeEnum - "size" varchar(255) NOT NULL, + "size" text NOT NULL, -- The timestamp the survey was taken. - "timestamp" timestamp NULL DEFAULT CURRENT_TIMESTAMP + "timestamp" timestamp NULL DEFAULT CURRENT_TIMESTAMP, -- Whether the survey has been exhausted. "exhausted" boolean NOT NULL ); - diff --git a/packages/db/sql/tables/05_faction.sql b/packages/db/sql/tables/05_faction.sql new file mode 100644 index 00000000..7dba4f19 --- /dev/null +++ b/packages/db/sql/tables/05_faction.sql @@ -0,0 +1,7 @@ +-- Describes a faction from the API. +CREATE TABLE IF NOT EXISTS "faction_" ( + -- The unique identifier for the faction. + "symbol" text NOT NULL PRIMARY KEY, + -- The faction encoded as json + "json" json NOT NULL +); \ No newline at end of file diff --git a/packages/ui/lib/main.dart b/packages/ui/lib/main.dart index 7c319a13..bf7df9fb 100644 --- a/packages/ui/lib/main.dart +++ b/packages/ui/lib/main.dart @@ -1,6 +1,5 @@ import 'dart:io'; -import 'package:cli/cache/faction_cache.dart'; import 'package:cli/cache/ship_cache.dart'; import 'package:cli/cache/systems_cache.dart'; import 'package:cli/logger.dart'; @@ -8,16 +7,11 @@ import 'package:file/local.dart'; import 'package:flutter/material.dart'; import 'package:http/http.dart' as http; import 'package:scoped/scoped.dart'; -import 'package:types/types.dart'; import 'package:ui/route.dart'; const fs = LocalFileSystem(); late SystemsCache systemsCache; late ShipCache shipCache; -late FactionCache factionCache; -final factionSystems = factionCache.factions - .map((f) => WaypointSymbol.fromString(f.headquarters).system) - .toSet(); const shipsUrl = 'http://localhost:8080/ships'; @@ -39,7 +33,6 @@ void main() async { values: {loggerRef}, ); shipCache = await loadShips(); - factionCache = await FactionCache.loadUnauthenticated(fs); runApp(const MyApp()); } diff --git a/packages/ui/lib/map.dart b/packages/ui/lib/map.dart index fb0e0256..dc4c36b6 100644 --- a/packages/ui/lib/map.dart +++ b/packages/ui/lib/map.dart @@ -81,12 +81,6 @@ class SystemMapPainter extends CustomPainter { final scale = 1.0 + (ships.length * 1.0); return SystemAttributes(color, scale); } - final factionSystems = factionCache.factions - .map((f) => WaypointSymbol.fromString(f.headquarters).system) - .toSet(); - if (factionSystems.contains(system.symbol)) { - return const SystemAttributes(Colors.blue, 3); - } return SystemAttributes(Colors.grey.shade700, 1); }