From 17c6ef7f4c64f4e5d23c4bc39299e449e7b71770 Mon Sep 17 00:00:00 2001 From: Dave Walker Date: Fri, 16 Jan 2026 14:42:30 +0000 Subject: [PATCH] Added location import to the management application --- data/location-import-template.xlsx | Bin 0 -> 6066 bytes sql/cleardown-all-tables.sql | 23 ++++++++++++++++++ sql/cleardown-operators.sql | 2 ++ sql/create-test-voyage.sql | 22 +++++++++++++++++ .../Config/ManagerCommandLineParser.cs | 1 + .../Config/CommandLineOptionType.cs | 1 + .../Logic/ImportHandler.cs | 8 ++++++ src/ShippingRecorder.Manager/Program.cs | 6 +++++ 8 files changed, 63 insertions(+) create mode 100644 data/location-import-template.xlsx create mode 100644 sql/cleardown-all-tables.sql create mode 100644 sql/cleardown-operators.sql create mode 100644 sql/create-test-voyage.sql diff --git a/data/location-import-template.xlsx b/data/location-import-template.xlsx new file mode 100644 index 0000000000000000000000000000000000000000..a824b3bf4566ef3e54b240b512d2211776aa9603 GIT binary patch literal 6066 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 O412X<88Y*8+x`y>95##q literal 0 HcmV?d00001 diff --git a/sql/cleardown-all-tables.sql b/sql/cleardown-all-tables.sql new file mode 100644 index 0000000..aa352c9 --- /dev/null +++ b/sql/cleardown-all-tables.sql @@ -0,0 +1,23 @@ +DELETE FROM SIGHTING; +DELETE FROM REGISTRATION_HISTORY; +DELETE FROM VOYAGE_EVENT; +DELETE FROM VOYAGE; +DELETE FROM PORT; +DELETE FROM VESSEL; +DELETE FROM COUNTRY; +DELETE FROM JOB_STATUS; +DELETE FROM LOCATION; +DELETE FROM OPERATOR; +DELETE FROM VESSEL_TYPE; + +DELETE FROM SQLITE_SEQUENCE WHERE NAME='SIGHTING'; +DELETE FROM SQLITE_SEQUENCE WHERE NAME='REGISTRATION_HISTORY'; +DELETE FROM SQLITE_SEQUENCE WHERE NAME='VOYAGE_EVENT'; +DELETE FROM SQLITE_SEQUENCE WHERE NAME='VOYAGE'; +DELETE FROM SQLITE_SEQUENCE WHERE NAME='PORT'; +DELETE FROM SQLITE_SEQUENCE WHERE NAME='VESSEL'; +DELETE FROM SQLITE_SEQUENCE WHERE NAME='COUNTRY'; +DELETE FROM SQLITE_SEQUENCE WHERE NAME='JOB_STATUS'; +DELETE FROM SQLITE_SEQUENCE WHERE NAME='LOCATION'; +DELETE FROM SQLITE_SEQUENCE WHERE NAME='OPERATOR'; +DELETE FROM SQLITE_SEQUENCE WHERE NAME='VESSEL_TYPE'; diff --git a/sql/cleardown-operators.sql b/sql/cleardown-operators.sql new file mode 100644 index 0000000..b1413b6 --- /dev/null +++ b/sql/cleardown-operators.sql @@ -0,0 +1,2 @@ +DELETE FROM OPERATOR; +DELETE FROM SQLITE_SEQUENCE WHERE name='OPERATOR'; diff --git a/sql/create-test-voyage.sql b/sql/create-test-voyage.sql new file mode 100644 index 0000000..bc634e1 --- /dev/null +++ b/sql/create-test-voyage.sql @@ -0,0 +1,22 @@ +SELECT * FROM PORT WHERE Code IN ( 'GBSOU', 'BEZEE' ); +/* +6901 22 BEZEE Zeebrugge +59315 235 GBSOU Southampton +*/ +SELECT * FROM OPERATOR WHERE Name LIKE 'P&O%'; +/* +310 P&O Cruises +311 P&O Cruises Australia +*/ +SELECT v.* +FROM VESSEL v +INNER JOIN REGISTRATION_HISTORY rh ON rh.Vessel_Id = v.Id +WHERE rh.Name = 'Arcadia'; +-- 3 9226906 2005 8.2 285 33 +INSERT INTO VOYAGE ( Operator_Id, Vessel_ID, Number ) VALUES ( 310, 3, 'I413' ); +SELECT * FROM VOYAGE WHERE Number = 'I413'; +-- 1 I413 310 3 +INSERT INTO VOYAGE_EVENT ( Voyage_Id, Event_Type, Port_Id, Date ) VALUES ( 1, 0, 59315, '2024-05-14 00:00:00' ); +INSERT INTO VOYAGE_EVENT ( Voyage_Id, Event_Type, Port_Id, Date ) VALUES ( 1, 1, 6901, '2024-05-15 00:00:00' ); +INSERT INTO VOYAGE_EVENT ( Voyage_Id, Event_Type, Port_Id, Date ) VALUES ( 1, 0, 6901, '2024-05-15 00:00:00' ); +INSERT INTO VOYAGE_EVENT ( Voyage_Id, Event_Type, Port_Id, Date ) VALUES ( 1, 1, 59315, '2024-05-17 00:00:00' ); diff --git a/src/ShippingRecorder.BusinessLogic/Config/ManagerCommandLineParser.cs b/src/ShippingRecorder.BusinessLogic/Config/ManagerCommandLineParser.cs index bba982d..34722a1 100644 --- a/src/ShippingRecorder.BusinessLogic/Config/ManagerCommandLineParser.cs +++ b/src/ShippingRecorder.BusinessLogic/Config/ManagerCommandLineParser.cs @@ -10,6 +10,7 @@ public ManagerCommandLineParser(IHelpGenerator generator) : base(generator) Add(CommandLineOptionType.Help, false, "--help", "-h", "Show command line help", 0, 0); Add(CommandLineOptionType.Update, false, "--update", "-u", "Apply the latest database migrations", 0, 0); Add(CommandLineOptionType.ImportCountries, false, "--import-countries", "-ic", "Import countries from a CSV file", 1, 1); + Add(CommandLineOptionType.ImportLocations, false, "--import-locations", "-il", "Import locations from a CSV file", 1, 1); Add(CommandLineOptionType.ImportOperators, false, "--import-operators", "-io", "Import operators from a CSV file", 1, 1); Add(CommandLineOptionType.ImportVesselTypes, false, "--import-vessel-types", "-ivt", "Import vessel types from a CSV file", 1, 1); Add(CommandLineOptionType.ImportVessels, false, "--import-vessels", "-iv", "Import vessels from a CSV file", 1, 1); diff --git a/src/ShippingRecorder.Entities/Config/CommandLineOptionType.cs b/src/ShippingRecorder.Entities/Config/CommandLineOptionType.cs index 372d5a8..1fd5a63 100644 --- a/src/ShippingRecorder.Entities/Config/CommandLineOptionType.cs +++ b/src/ShippingRecorder.Entities/Config/CommandLineOptionType.cs @@ -12,6 +12,7 @@ public enum CommandLineOptionType ExportVesselTypes, Help, ImportCountries, + ImportLocations, ImportOperators, ImportPorts, ImportSightings, diff --git a/src/ShippingRecorder.Manager/Logic/ImportHandler.cs b/src/ShippingRecorder.Manager/Logic/ImportHandler.cs index f0e5916..c8f7ee9 100644 --- a/src/ShippingRecorder.Manager/Logic/ImportHandler.cs +++ b/src/ShippingRecorder.Manager/Logic/ImportHandler.cs @@ -68,6 +68,14 @@ private async Task HandleImport(CommandLineOptionType type, string pattern public async Task HandleCountryImportAsync() => await HandleImport(CommandLineOptionType.ImportCountries, ExportableCountry.CsvRecordPattern); + + /// + /// Handle the locations import command + /// + /// + public async Task HandleLocationImportAsync() + => await HandleImport(CommandLineOptionType.ImportLocations, ExportableLocation.CsvRecordPattern); + /// /// Handle the operators import command /// diff --git a/src/ShippingRecorder.Manager/Program.cs b/src/ShippingRecorder.Manager/Program.cs index 90e45f7..d7bc620 100644 --- a/src/ShippingRecorder.Manager/Program.cs +++ b/src/ShippingRecorder.Manager/Program.cs @@ -69,6 +69,12 @@ public static async Task Main(string[] args) await new ImportHandler(settings, parser, factory).HandleCountryImportAsync(); } + // If a CSV file containing locations details has been supplied, import it + if (parser.IsPresent(CommandLineOptionType.ImportLocations)) + { + await new ImportHandler(settings, parser, factory).HandleLocationImportAsync(); + } + // If a CSV file containing operator details has been supplied, import it if (parser.IsPresent(CommandLineOptionType.ImportOperators)) {