From 73dc06d78fbbe329136770d76c0a96d5c82b3685 Mon Sep 17 00:00:00 2001 From: The Magician Date: Thu, 26 Sep 2024 13:17:55 +0100 Subject: [PATCH] Implement import, rework CLI to allow top-level arguments before subcommand --- sevenkeys/database/storagearea.go | 23 ++++++++++++++++- sevenkeys/logic/storage.go | 41 +++++++++++++++++++++++++------ sevenkeys/main.go | 28 +++++++++++++++------ 3 files changed, 77 insertions(+), 15 deletions(-) diff --git a/sevenkeys/database/storagearea.go b/sevenkeys/database/storagearea.go index 1808a50..42b41e5 100644 --- a/sevenkeys/database/storagearea.go +++ b/sevenkeys/database/storagearea.go @@ -1,6 +1,11 @@ package database -import "database/sql" +import ( + "database/sql" + "errors" +) + +var ErrStorageAreaDoesNotExist error = errors.New("Storage area does not exist.") var StorageAreaTypeBinder string = "Binder" var StorageAreaTypeBox string = "Box" @@ -34,6 +39,22 @@ func GetAllStorageAreas(db *sql.DB) ([]StorageArea, error) { return storageAreas, nil } +func GetStorageAreaIdByName(db *sql.DB, storageAreaName string) (int, error) { + var storageAreaId int + + query := `SELECT Id FROM StorageArea WHERE Name = ?;` + row := db.QueryRow(query, storageAreaName) + + err := row.Scan(&storageAreaId) + if err == sql.ErrNoRows { + return storageAreaId, ErrStorageAreaDoesNotExist + } else if err != nil { + return storageAreaId, err + } + + return storageAreaId, nil +} + func GetStorageAreaTypeById(db *sql.DB, storageAreaId int) (string, error) { var storageType string diff --git a/sevenkeys/logic/storage.go b/sevenkeys/logic/storage.go index 2f3b4e6..c1b9409 100644 --- a/sevenkeys/logic/storage.go +++ b/sevenkeys/logic/storage.go @@ -2,10 +2,34 @@ package logic import ( "database/sql" + "errors" "sevenkeys/database" ) -type StorageAreaSearchOptions map[string]int +var ErrCouldNotGetStorageAreaId error = errors.New("Could not get storage area ID.") + +func GetStorageAreaId(db *sql.DB, storageAreaName string) (int, error) { + id, err := database.GetStorageAreaIdByName(db, storageAreaName) + if err == nil { + return id, nil + } + + if err == database.ErrStorageAreaDoesNotExist { + storageOptions, err := GetStorageAreaSearchOptions(db) + if err != nil { + return id, err + } + + id, _, err := GenericSearch(storageOptions) + if err == nil { + return id, nil + } + + return id, ErrCouldNotGetStorageAreaId + } + + return id, ErrCouldNotGetStorageAreaId +} func CreateStorageArea(db *sql.DB, storageArea database.StorageArea) error { // TODO: Check if there's already a storage are with the same name @@ -18,8 +42,10 @@ func CreateStorageArea(db *sql.DB, storageArea database.StorageArea) error { return nil } +type StorageAreaSearchOptions map[string]int + func GetStorageAreaSearchOptions(db *sql.DB) (StorageAreaSearchOptions, error) { - var options StorageAreaSearchOptions + var options StorageAreaSearchOptions = make(map[string]int) storageAreas, err := database.GetAllStorageAreas(db) if err != nil { @@ -33,7 +59,7 @@ func GetStorageAreaSearchOptions(db *sql.DB) (StorageAreaSearchOptions, error) { return options, nil } -func StoreAfterLastCard(db *sql.DB, cardLocation database.CardLocation) error { +func storeAfterLastCard(db *sql.DB, cardLocation database.CardLocation) error { lastPosition, err := database.GetLastPositionInStorageArea(db, cardLocation.StorageAreaId) if err != nil { return err @@ -49,7 +75,7 @@ func StoreAfterLastCard(db *sql.DB, cardLocation database.CardLocation) error { return nil } -func StoreInEmptySlot(db *sql.DB, cardLocation database.CardLocation, cardLocationId int) error { +func storeInEmptySlot(db *sql.DB, cardLocation database.CardLocation, cardLocationId int) error { cardLocation.Id = cardLocationId err := database.InsertCardInExistingLocation(db, cardLocation) if err != nil { @@ -69,14 +95,14 @@ func StoreCard(db *sql.DB, cardLocation database.CardLocation) error { nextEmptySlotId, err := database.GetNextEmptySlotInBinder(db, cardLocation.StorageAreaId) if err == sql.ErrNoRows { - err = StoreAfterLastCard(db, cardLocation) + err = storeAfterLastCard(db, cardLocation) if err != nil { return err } } else if err != nil { return err } else { - err = StoreInEmptySlot(db, cardLocation, nextEmptySlotId) + err = storeInEmptySlot(db, cardLocation, nextEmptySlotId) if err != nil { return err } @@ -85,9 +111,10 @@ func StoreCard(db *sql.DB, cardLocation database.CardLocation) error { return nil } - err = StoreAfterLastCard(db, cardLocation) + err = storeAfterLastCard(db, cardLocation) if err != nil { return err } + return nil } diff --git a/sevenkeys/main.go b/sevenkeys/main.go index 3830fed..480d7a6 100644 --- a/sevenkeys/main.go +++ b/sevenkeys/main.go @@ -6,7 +6,9 @@ import ( "os" "sevenkeys/cli" "sevenkeys/database" + "sevenkeys/delverlens" "sevenkeys/figlet" + "sevenkeys/logic" ) const ( @@ -14,7 +16,10 @@ const ( ) func main() { - profile := os.Getenv("SEVENKEYS_PROFILE") + var profile string + flag.StringVar(&profile, "profile", "development", "The database profile to use.") + + flag.Parse() db := database.GetDatabaseFromConfig("config." + profile + ".json") figlet.ReadFigletFonts() @@ -27,18 +32,27 @@ func main() { importCmd := flag.NewFlagSet("import", flag.ExitOnError) storageArea := importCmd.String("storagearea", "", "The name of the StorageArea where cards should be imported.") - if len(os.Args) < 2 { + if len(flag.Args()) == 0 { fmt.Fprintln(os.Stderr, "Please specify a subcommand.") os.Exit(1) } - switch os.Args[1] { + switch flag.Args()[0] { case ImportSubcommand: - // TODO: Get filename, run import code - importCmd.Parse(os.Args[2:]) - //storageAreaId := logic.GetStorageAreaIdByName(db, *storageArea) + importCmd.Parse(flag.Args()[1:]) - fmt.Printf("Filename: %s\n", importCmd.Args()[0]) + storageAreaId, err := logic.GetStorageAreaId(db, *storageArea) + if err == logic.ErrCouldNotGetStorageAreaId { + fmt.Fprintf(os.Stderr, "[sevenkeys] No storage area was selected, exiting.\n") + os.Exit(1) + } + logic.Check(err) + + delverLensCards, err := delverlens.ParseExportFile(importCmd.Args()[0]) + logic.Check(err) + + err = logic.ImportDelverLensCards(db, delverLensCards, storageAreaId) + logic.Check(err) break default: fmt.Fprintf(os.Stderr, "Unrecognized subcommand: %s\n", os.Args[1])