Compare commits
10 Commits
1e967674b6
...
70f0b4d4f7
Author | SHA1 | Date |
---|---|---|
The Magician | 70f0b4d4f7 | |
The Magician | 95f45a98fa | |
The Magician | 3ef49bc72c | |
The Magician | 2ecb448e29 | |
The Magician | b2946d00e2 | |
The Magician | 61127a1f92 | |
The Magician | d89716be4b | |
The Magician | 86200a9afc | |
The Magician | 1a3190ad40 | |
The Magician | e860e529f1 |
|
@ -4,9 +4,9 @@ import (
|
||||||
"database/sql"
|
"database/sql"
|
||||||
"errors"
|
"errors"
|
||||||
"fmt"
|
"fmt"
|
||||||
"os"
|
|
||||||
"os/exec"
|
"os/exec"
|
||||||
"sevenkeys/database"
|
"sevenkeys/database"
|
||||||
|
"sevenkeys/delverlens"
|
||||||
"sevenkeys/logic"
|
"sevenkeys/logic"
|
||||||
)
|
)
|
||||||
|
|
||||||
|
@ -15,7 +15,7 @@ var output string
|
||||||
func MainCliLoop(db *sql.DB) {
|
func MainCliLoop(db *sql.DB) {
|
||||||
var command string
|
var command string
|
||||||
|
|
||||||
var selectedStorageArea database.StorageArea
|
//var selectedStorageAreaName string
|
||||||
var cardLocation database.CardLocation
|
var cardLocation database.CardLocation
|
||||||
|
|
||||||
var insertSearchCriteria logic.SearchCriteria = logic.SearchCriteria{
|
var insertSearchCriteria logic.SearchCriteria = logic.SearchCriteria{
|
||||||
|
@ -26,17 +26,18 @@ func MainCliLoop(db *sql.DB) {
|
||||||
}
|
}
|
||||||
var insertSearchOptions logic.InsertSearchOptions
|
var insertSearchOptions logic.InsertSearchOptions
|
||||||
|
|
||||||
// TODO: Make these do something and add the ability to modify them
|
// TODO: Add the ability to modify this
|
||||||
var locateSearchCriteria logic.SearchCriteria = logic.SearchCriteria{
|
var locateSearchCriteria logic.SearchCriteria = logic.SearchCriteria{
|
||||||
SetCode: "",
|
SetCode: "",
|
||||||
Foil: logic.Either,
|
Foil: logic.True,
|
||||||
Promo: logic.Either,
|
Promo: logic.Either,
|
||||||
Language: "en",
|
Language: "en",
|
||||||
}
|
}
|
||||||
|
|
||||||
for {
|
for {
|
||||||
ShowSplashScreen()
|
ShowSplashScreen()
|
||||||
showStorageInfo(os.Stdout, selectedStorageArea)
|
// TODO: Fix this
|
||||||
|
//showStorageInfo(os.Stdout, selectedStorageAreaName)
|
||||||
showInsertSearchCriteria(insertSearchCriteria)
|
showInsertSearchCriteria(insertSearchCriteria)
|
||||||
showSelectedCard()
|
showSelectedCard()
|
||||||
showCopiesInserted()
|
showCopiesInserted()
|
||||||
|
@ -56,10 +57,14 @@ func MainCliLoop(db *sql.DB) {
|
||||||
logic.Check(err)
|
logic.Check(err)
|
||||||
break
|
break
|
||||||
case "a", "area":
|
case "a", "area":
|
||||||
area, err := logic.SelectStorageArea(db)
|
options, err := logic.GetStorageAreaSearchOptions(db)
|
||||||
logic.Check(err)
|
logic.Check(err)
|
||||||
selectedStorageArea = area
|
|
||||||
cardLocation.StorageAreaId = area.Id
|
id, _, err := logic.GenericSearch(options)
|
||||||
|
logic.Check(err)
|
||||||
|
|
||||||
|
//selectedStorageAreaName = name
|
||||||
|
cardLocation.StorageAreaId = id
|
||||||
break
|
break
|
||||||
case "c", "criteria":
|
case "c", "criteria":
|
||||||
insertSearchCriteria = getSearchCriteria()
|
insertSearchCriteria = getSearchCriteria()
|
||||||
|
@ -71,8 +76,9 @@ func MainCliLoop(db *sql.DB) {
|
||||||
|
|
||||||
var previousCardPrintingId = cardLocation.CardPrintingId
|
var previousCardPrintingId = cardLocation.CardPrintingId
|
||||||
|
|
||||||
pk, err := logic.GenericSearch(insertSearchOptions)
|
pk, searchLine, err := logic.GenericSearch(insertSearchOptions)
|
||||||
cardLocation.CardPrintingId = pk
|
cardLocation.CardPrintingId = pk
|
||||||
|
selectedCardPrintingSearchLine = searchLine
|
||||||
|
|
||||||
var exitError *exec.ExitError
|
var exitError *exec.ExitError
|
||||||
if errors.As(err, &exitError) {
|
if errors.As(err, &exitError) {
|
||||||
|
@ -86,7 +92,18 @@ func MainCliLoop(db *sql.DB) {
|
||||||
}
|
}
|
||||||
break
|
break
|
||||||
case "i", "insert":
|
case "i", "insert":
|
||||||
insertSelectedCard(db, selectedStorageArea, cardLocation)
|
err := logic.StoreCard(db, cardLocation)
|
||||||
|
logic.Check(err)
|
||||||
|
copiesInserted++
|
||||||
|
break
|
||||||
|
case "d", "delverlens":
|
||||||
|
filename := GetStringResponse("Filename:")
|
||||||
|
|
||||||
|
cards, err := delverlens.ParseExportFile(filename)
|
||||||
|
logic.Check(err)
|
||||||
|
|
||||||
|
err = logic.ImportDelverLensCards(cards)
|
||||||
|
logic.Check(err)
|
||||||
break
|
break
|
||||||
case "l", "locate":
|
case "l", "locate":
|
||||||
filename := GetStringResponse("Filename:")
|
filename := GetStringResponse("Filename:")
|
||||||
|
@ -96,11 +113,32 @@ func MainCliLoop(db *sql.DB) {
|
||||||
locations, err := logic.LocateCards(db, cardNames, locateSearchCriteria)
|
locations, err := logic.LocateCards(db, cardNames, locateSearchCriteria)
|
||||||
logic.Check(err)
|
logic.Check(err)
|
||||||
|
|
||||||
for _, location := range locations {
|
if len(locations) == 0 {
|
||||||
fmt.Println(location)
|
fmt.Println("No results found")
|
||||||
|
fmt.Scanln()
|
||||||
|
break
|
||||||
}
|
}
|
||||||
fmt.Scanln()
|
|
||||||
|
|
||||||
|
for _, location := range locations {
|
||||||
|
description := logic.GetLocationDescription(location)
|
||||||
|
fmt.Println(description)
|
||||||
|
|
||||||
|
for true {
|
||||||
|
todo := GetStringResponse("TODO:")
|
||||||
|
|
||||||
|
if todo == "r" {
|
||||||
|
logic.RemoveFromStorage(db, location)
|
||||||
|
break
|
||||||
|
} else if todo == "n" {
|
||||||
|
break
|
||||||
|
} else {
|
||||||
|
fmt.Printf("Unrecognized option: %s\n", todo)
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
fmt.Println("Though this query has ended, its relics still slumber in New Argive.")
|
||||||
|
fmt.Scanln()
|
||||||
break
|
break
|
||||||
default:
|
default:
|
||||||
fmt.Println("Unrecognized command:", command)
|
fmt.Println("Unrecognized command:", command)
|
||||||
|
|
|
@ -1,11 +1,9 @@
|
||||||
package cli
|
package cli
|
||||||
|
|
||||||
import (
|
import (
|
||||||
"database/sql"
|
|
||||||
"fmt"
|
"fmt"
|
||||||
"io"
|
"io"
|
||||||
"sevenkeys/database"
|
"sevenkeys/database"
|
||||||
"sevenkeys/logic"
|
|
||||||
)
|
)
|
||||||
|
|
||||||
var (
|
var (
|
||||||
|
@ -36,20 +34,3 @@ func showStorageInfo(w io.Writer, area database.StorageArea) {
|
||||||
func showCopiesInserted() {
|
func showCopiesInserted() {
|
||||||
fmt.Println("Copies inserted:", copiesInserted)
|
fmt.Println("Copies inserted:", copiesInserted)
|
||||||
}
|
}
|
||||||
|
|
||||||
func insertSelectedCard(db *sql.DB, area database.StorageArea, location database.CardLocation) {
|
|
||||||
if area.Name == "" {
|
|
||||||
output = "No storage area selected."
|
|
||||||
return
|
|
||||||
}
|
|
||||||
|
|
||||||
if location.CardPrintingId == "" {
|
|
||||||
output = "No card selected, please [search] for a card printing."
|
|
||||||
return
|
|
||||||
}
|
|
||||||
|
|
||||||
err := logic.StoreCard(db, location)
|
|
||||||
logic.Check(err)
|
|
||||||
|
|
||||||
copiesInserted++
|
|
||||||
}
|
|
||||||
|
|
|
@ -43,3 +43,19 @@ func InsertCardLocation(db *sql.DB, storageLocation CardLocation) error {
|
||||||
|
|
||||||
return nil
|
return nil
|
||||||
}
|
}
|
||||||
|
|
||||||
|
func InsertCardInExistingLocation(db *sql.DB, cardLocation CardLocation) error {
|
||||||
|
query := `UPDATE CardLocation SET CardPrintingId = ? WHERE Id = ?;`
|
||||||
|
|
||||||
|
update, err := db.Prepare(query)
|
||||||
|
if err != nil {
|
||||||
|
return err
|
||||||
|
}
|
||||||
|
|
||||||
|
_, err = update.Exec(cardLocation.CardPrintingId, cardLocation.Id)
|
||||||
|
if err != nil {
|
||||||
|
return err
|
||||||
|
}
|
||||||
|
|
||||||
|
return nil
|
||||||
|
}
|
||||||
|
|
|
@ -7,12 +7,14 @@ import (
|
||||||
)
|
)
|
||||||
|
|
||||||
type LocateCardResult struct {
|
type LocateCardResult struct {
|
||||||
|
CardLocationId int
|
||||||
CardName string
|
CardName string
|
||||||
SetCode string
|
SetCode string
|
||||||
IsFoil bool
|
IsFoil bool
|
||||||
IsPromo bool
|
IsPromo bool
|
||||||
CollectorNumber string
|
CollectorNumber string
|
||||||
Language string
|
Language string
|
||||||
|
StorageAreaId int
|
||||||
StorageAreaType string
|
StorageAreaType string
|
||||||
StorageAreaName string
|
StorageAreaName string
|
||||||
Position int
|
Position int
|
||||||
|
@ -21,7 +23,21 @@ type LocateCardResult struct {
|
||||||
func GetLocateResults(db *sql.DB, cardNames []string) ([]LocateCardResult, error) {
|
func GetLocateResults(db *sql.DB, cardNames []string) ([]LocateCardResult, error) {
|
||||||
var results []LocateCardResult
|
var results []LocateCardResult
|
||||||
|
|
||||||
query := "SELECT CardPrinting.Name, CardPrinting.SetCode, CardPrinting.IsFoil, CardPrinting.IsPromo, CardPrinting.CollectorNumber, CardPrinting.Language, StorageArea.StorageType, StorageArea.Name, CardLocation.Position FROM CardLocation JOIN CardPrinting ON CardLocation.CardPrintingId = CardPrinting.Id JOIN StorageArea ON CardLocation.StorageAreaId = StorageArea.Id WHERE CardPrinting.Name IN (?);"
|
query := `SELECT CardLocation.Id,
|
||||||
|
CardPrinting.Name,
|
||||||
|
CardPrinting.SetCode,
|
||||||
|
CardPrinting.IsFoil,
|
||||||
|
CardPrinting.IsPromo,
|
||||||
|
CardPrinting.CollectorNumber,
|
||||||
|
CardPrinting.Language,
|
||||||
|
StorageArea.Id,
|
||||||
|
StorageArea.StorageType,
|
||||||
|
StorageArea.Name,
|
||||||
|
CardLocation.Position
|
||||||
|
FROM CardLocation
|
||||||
|
JOIN CardPrinting ON CardLocation.CardPrintingId = CardPrinting.Id
|
||||||
|
JOIN StorageArea ON CardLocation.StorageAreaId = StorageArea.Id
|
||||||
|
WHERE CardPrinting.Name IN (?);`
|
||||||
query, args, err := sqlx.In(query, cardNames)
|
query, args, err := sqlx.In(query, cardNames)
|
||||||
if err != nil {
|
if err != nil {
|
||||||
return results, err
|
return results, err
|
||||||
|
@ -35,7 +51,7 @@ func GetLocateResults(db *sql.DB, cardNames []string) ([]LocateCardResult, error
|
||||||
|
|
||||||
var result LocateCardResult
|
var result LocateCardResult
|
||||||
for rows.Next() {
|
for rows.Next() {
|
||||||
err := rows.Scan(&result.CardName, &result.SetCode, &result.IsFoil, &result.IsPromo, &result.CollectorNumber, &result.Language, &result.StorageAreaType, &result.StorageAreaName, &result.Position)
|
err := rows.Scan(&result.CardLocationId, &result.CardName, &result.SetCode, &result.IsFoil, &result.IsPromo, &result.CollectorNumber, &result.Language, &result.StorageAreaId, &result.StorageAreaType, &result.StorageAreaName, &result.Position)
|
||||||
if err != nil {
|
if err != nil {
|
||||||
return results, err
|
return results, err
|
||||||
}
|
}
|
||||||
|
|
|
@ -2,8 +2,8 @@ package database
|
||||||
|
|
||||||
import "database/sql"
|
import "database/sql"
|
||||||
|
|
||||||
func RemoveFromBinder(db *sql.DB, location CardLocation) error {
|
func RemoveFromBinder(db *sql.DB, location LocateCardResult) error {
|
||||||
query := `UPDATE CardStorageLocation SET CardPrintingId = NULL WHERE Id = ?;`
|
query := `UPDATE CardLocation SET CardPrintingId = NULL WHERE Id = ?;`
|
||||||
|
|
||||||
update, err := db.Prepare(query)
|
update, err := db.Prepare(query)
|
||||||
defer update.Close()
|
defer update.Close()
|
||||||
|
@ -11,7 +11,7 @@ func RemoveFromBinder(db *sql.DB, location CardLocation) error {
|
||||||
return err
|
return err
|
||||||
}
|
}
|
||||||
|
|
||||||
_, err = update.Exec(location.Id)
|
_, err = update.Exec(location.CardLocationId)
|
||||||
if err != nil {
|
if err != nil {
|
||||||
return err
|
return err
|
||||||
}
|
}
|
||||||
|
@ -19,8 +19,8 @@ func RemoveFromBinder(db *sql.DB, location CardLocation) error {
|
||||||
return nil
|
return nil
|
||||||
}
|
}
|
||||||
|
|
||||||
func RemoveFromBox(db *sql.DB, location CardLocation) error {
|
func RemoveFromBox(db *sql.DB, location LocateCardResult) error {
|
||||||
deleteQuery := `DELETE FROM CardStorageLocation WHERE Id = ?;`
|
deleteQuery := `DELETE FROM CardLocation WHERE Id = ?;`
|
||||||
|
|
||||||
del, err := db.Prepare(deleteQuery)
|
del, err := db.Prepare(deleteQuery)
|
||||||
defer del.Close()
|
defer del.Close()
|
||||||
|
@ -28,12 +28,12 @@ func RemoveFromBox(db *sql.DB, location CardLocation) error {
|
||||||
return err
|
return err
|
||||||
}
|
}
|
||||||
|
|
||||||
_, err = del.Exec(location.Id)
|
_, err = del.Exec(location.CardLocationId)
|
||||||
if err != nil {
|
if err != nil {
|
||||||
return err
|
return err
|
||||||
}
|
}
|
||||||
|
|
||||||
updateQuery := `UPDATE CardStorageLocation SET Position = Position - 1 WHERE Position > 5;`
|
updateQuery := `UPDATE CardLocation SET Position = Position - 1 WHERE Position > ? AND StorageAreaId = ?;`
|
||||||
|
|
||||||
update, err := db.Prepare(updateQuery)
|
update, err := db.Prepare(updateQuery)
|
||||||
defer update.Close()
|
defer update.Close()
|
||||||
|
@ -41,7 +41,7 @@ func RemoveFromBox(db *sql.DB, location CardLocation) error {
|
||||||
return err
|
return err
|
||||||
}
|
}
|
||||||
|
|
||||||
_, err = update.Exec(location.Id)
|
_, err = update.Exec(location.Position, location.StorageAreaId)
|
||||||
if err != nil {
|
if err != nil {
|
||||||
return err
|
return err
|
||||||
}
|
}
|
||||||
|
|
|
@ -34,6 +34,34 @@ func GetAllStorageAreas(db *sql.DB) ([]StorageArea, error) {
|
||||||
return storageAreas, nil
|
return storageAreas, nil
|
||||||
}
|
}
|
||||||
|
|
||||||
|
func GetStorageAreaTypeById(db *sql.DB, storageAreaId int) (string, error) {
|
||||||
|
var storageType string
|
||||||
|
|
||||||
|
query := `SELECT StorageType FROM StorageArea WHERE Id = ?;`
|
||||||
|
row := db.QueryRow(query, storageAreaId)
|
||||||
|
|
||||||
|
err := row.Scan(&storageType)
|
||||||
|
if err != nil {
|
||||||
|
return storageType, err
|
||||||
|
}
|
||||||
|
|
||||||
|
return storageType, nil
|
||||||
|
}
|
||||||
|
|
||||||
|
func GetNextEmptySlotInBinder(db *sql.DB, storageAreaId int) (int, error) {
|
||||||
|
query := `SELECT Id FROM CardLocation WHERE CardPrintingId IS NULL AND StorageAreaId = ? ORDER BY Position ASC LIMIT 1;`
|
||||||
|
|
||||||
|
var emptySlotId int
|
||||||
|
err := db.QueryRow(query, storageAreaId).Scan(&emptySlotId)
|
||||||
|
if err == sql.ErrNoRows {
|
||||||
|
return -1, nil
|
||||||
|
} else if err != nil {
|
||||||
|
return 0, err
|
||||||
|
}
|
||||||
|
|
||||||
|
return emptySlotId, nil
|
||||||
|
}
|
||||||
|
|
||||||
func InsertStorageArea(db *sql.DB, storageArea StorageArea) error {
|
func InsertStorageArea(db *sql.DB, storageArea StorageArea) error {
|
||||||
query := `INSERT INTO StorageArea (Name, StorageType) VALUES (?, ?);`
|
query := `INSERT INTO StorageArea (Name, StorageType) VALUES (?, ?);`
|
||||||
|
|
||||||
|
@ -49,17 +77,3 @@ func InsertStorageArea(db *sql.DB, storageArea StorageArea) error {
|
||||||
|
|
||||||
return nil
|
return nil
|
||||||
}
|
}
|
||||||
|
|
||||||
func GetStorageAreaTypeById(db *sql.DB, storageAreaId int) (string, error) {
|
|
||||||
var storageType string
|
|
||||||
|
|
||||||
query := `SELECT StorageType FROM StorageArea WHERE Id = ?;`
|
|
||||||
row := db.QueryRow(query, storageAreaId)
|
|
||||||
|
|
||||||
err := row.Scan(&storageType)
|
|
||||||
if err != nil {
|
|
||||||
return storageType, err
|
|
||||||
}
|
|
||||||
|
|
||||||
return storageType, nil
|
|
||||||
}
|
|
||||||
|
|
|
@ -0,0 +1,50 @@
|
||||||
|
package delverlens
|
||||||
|
|
||||||
|
import (
|
||||||
|
"encoding/csv"
|
||||||
|
"io"
|
||||||
|
"os"
|
||||||
|
"strings"
|
||||||
|
)
|
||||||
|
|
||||||
|
type DelverLensCard struct {
|
||||||
|
ScryfallID string
|
||||||
|
IsFoil bool
|
||||||
|
}
|
||||||
|
|
||||||
|
func ParseExportFile(filename string) ([]DelverLensCard, error) {
|
||||||
|
var cards []DelverLensCard
|
||||||
|
|
||||||
|
file, err := os.Open("/home/viciouscirce/dox/sevenkeys_imports/" + filename)
|
||||||
|
if err != nil {
|
||||||
|
return cards, err
|
||||||
|
}
|
||||||
|
|
||||||
|
r := csv.NewReader(file)
|
||||||
|
|
||||||
|
var isHeader bool = true
|
||||||
|
for {
|
||||||
|
record, err := r.Read()
|
||||||
|
if err == io.EOF {
|
||||||
|
break
|
||||||
|
} else if err != nil {
|
||||||
|
return cards, err
|
||||||
|
}
|
||||||
|
|
||||||
|
// Skip the header line
|
||||||
|
if isHeader {
|
||||||
|
isHeader = false
|
||||||
|
continue
|
||||||
|
}
|
||||||
|
|
||||||
|
card := DelverLensCard{
|
||||||
|
Name: record[0],
|
||||||
|
IsFoil: record[1] == "Foil",
|
||||||
|
CollectorNumber: record[2],
|
||||||
|
SetCode: strings.ToLower(record[3]),
|
||||||
|
}
|
||||||
|
cards = append(cards, card)
|
||||||
|
}
|
||||||
|
|
||||||
|
return cards, nil
|
||||||
|
}
|
|
@ -0,0 +1,25 @@
|
||||||
|
package logic
|
||||||
|
|
||||||
|
import (
|
||||||
|
"database/sql"
|
||||||
|
"sevenkeys/database"
|
||||||
|
"sevenkeys/delverlens"
|
||||||
|
)
|
||||||
|
|
||||||
|
func ImportDelverLensCards(db *sql.DB, cards []delverlens.DelverLensCard, storageAreaId int) error {
|
||||||
|
for _, card := range cards {
|
||||||
|
var cardPrintingId string
|
||||||
|
if card.IsFoil {
|
||||||
|
cardPrintingId = card.ScryfallID + "n"
|
||||||
|
} else {
|
||||||
|
cardPrintingId = card.ScryfallID + "f"
|
||||||
|
}
|
||||||
|
|
||||||
|
cardLocation := database.CardLocation{
|
||||||
|
CardPrintingId: cardPrintingId,
|
||||||
|
StorageAreaId: storageAreaId,
|
||||||
|
}
|
||||||
|
|
||||||
|
StoreCard(cardLocation)
|
||||||
|
}
|
||||||
|
}
|
|
@ -9,9 +9,12 @@ import (
|
||||||
const SLOTS_PER_BINDER_PAGE = 18 // TODO: Make this configurable
|
const SLOTS_PER_BINDER_PAGE = 18 // TODO: Make this configurable
|
||||||
|
|
||||||
func GetBinderLocationDescription(position int) string {
|
func GetBinderLocationDescription(position int) string {
|
||||||
var page int = (position / SLOTS_PER_BINDER_PAGE) + 1
|
var page int = ((position - 1) / SLOTS_PER_BINDER_PAGE) + 1
|
||||||
|
|
||||||
var pagePosition int = position % SLOTS_PER_BINDER_PAGE
|
var pagePosition int = position % SLOTS_PER_BINDER_PAGE
|
||||||
|
if pagePosition == 0 {
|
||||||
|
pagePosition = SLOTS_PER_BINDER_PAGE
|
||||||
|
}
|
||||||
|
|
||||||
var slot int
|
var slot int
|
||||||
var frontOrBack string
|
var frontOrBack string
|
||||||
|
@ -27,15 +30,14 @@ func GetBinderLocationDescription(position int) string {
|
||||||
return fmt.Sprintf(" on page %d in %s slot %d", page, frontOrBack, slot)
|
return fmt.Sprintf(" on page %d in %s slot %d", page, frontOrBack, slot)
|
||||||
}
|
}
|
||||||
|
|
||||||
func LocateCards(db *sql.DB, cardNames []string, criteria SearchCriteria) ([]string, error) {
|
func LocateCards(db *sql.DB, cardNames []string, criteria SearchCriteria) ([]database.LocateCardResult, error) {
|
||||||
var locations []string
|
|
||||||
|
|
||||||
results, err := database.GetLocateResults(db, cardNames)
|
results, err := database.GetLocateResults(db, cardNames)
|
||||||
if err != nil {
|
if err != nil {
|
||||||
return locations, err
|
return results, err
|
||||||
}
|
}
|
||||||
|
|
||||||
var location string
|
var filteredResults []database.LocateCardResult
|
||||||
|
|
||||||
for _, result := range results {
|
for _, result := range results {
|
||||||
printing := database.CardPrinting{
|
printing := database.CardPrinting{
|
||||||
SetCode: result.SetCode,
|
SetCode: result.SetCode,
|
||||||
|
@ -49,31 +51,37 @@ func LocateCards(db *sql.DB, cardNames []string, criteria SearchCriteria) ([]str
|
||||||
continue
|
continue
|
||||||
}
|
}
|
||||||
|
|
||||||
location = fmt.Sprintf("%s (%s %s) [%s]",
|
filteredResults = append(filteredResults, result)
|
||||||
result.CardName,
|
|
||||||
result.SetCode,
|
|
||||||
result.CollectorNumber,
|
|
||||||
result.Language)
|
|
||||||
|
|
||||||
if result.IsFoil {
|
|
||||||
location += " FOIL"
|
|
||||||
}
|
|
||||||
if result.IsPromo {
|
|
||||||
location += " PROMO"
|
|
||||||
}
|
|
||||||
|
|
||||||
location += fmt.Sprintf(" in %s \"%s\"",
|
|
||||||
result.StorageAreaType,
|
|
||||||
result.StorageAreaName)
|
|
||||||
|
|
||||||
if result.StorageAreaType == "Binder" {
|
|
||||||
location += GetBinderLocationDescription(result.Position)
|
|
||||||
} else if result.StorageAreaType == "Box" {
|
|
||||||
location += fmt.Sprintf(" at position %d", result.Position)
|
|
||||||
}
|
|
||||||
|
|
||||||
locations = append(locations, location)
|
|
||||||
}
|
}
|
||||||
|
|
||||||
return locations, nil
|
return filteredResults, nil
|
||||||
|
}
|
||||||
|
|
||||||
|
func GetLocationDescription(location database.LocateCardResult) string {
|
||||||
|
var description string
|
||||||
|
|
||||||
|
description = fmt.Sprintf("%s (%s %s) [%s]",
|
||||||
|
location.CardName,
|
||||||
|
location.SetCode,
|
||||||
|
location.CollectorNumber,
|
||||||
|
location.Language)
|
||||||
|
|
||||||
|
if location.IsFoil {
|
||||||
|
description += " FOIL"
|
||||||
|
}
|
||||||
|
if location.IsPromo {
|
||||||
|
description += " PROMO"
|
||||||
|
}
|
||||||
|
|
||||||
|
description += fmt.Sprintf(" in %s \"%s\"",
|
||||||
|
location.StorageAreaType,
|
||||||
|
location.StorageAreaName)
|
||||||
|
|
||||||
|
if location.StorageAreaType == "Binder" {
|
||||||
|
description += GetBinderLocationDescription(location.Position)
|
||||||
|
} else if location.StorageAreaType == "Box" {
|
||||||
|
description += fmt.Sprintf(" at position %d", location.Position)
|
||||||
|
}
|
||||||
|
|
||||||
|
return description
|
||||||
}
|
}
|
||||||
|
|
|
@ -2,24 +2,44 @@ package logic
|
||||||
|
|
||||||
import "testing"
|
import "testing"
|
||||||
|
|
||||||
func Test_GetBinderLocationDescription_ReturnsCorrectFormat_ForFrontSlots(t *testing.T) {
|
func assert(t *testing.T, description string, expected string) {
|
||||||
var position int = 24
|
|
||||||
var expected string = " on page 2 in front slot 6"
|
|
||||||
|
|
||||||
description := GetBinderLocationDescription(position)
|
|
||||||
|
|
||||||
if description != expected {
|
if description != expected {
|
||||||
t.Errorf("expected %s, got %s\n", expected, description)
|
t.Errorf("expected \"%s\", got \"%s\"\n", expected, description)
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
func Test_GetBinderLocationDescription_ReturnsCorrectFormat_ForBackSlots(t *testing.T) {
|
func Test_GetBinderLocationDescription_ReturnsCorrectSlotNumber_ForFirstSlotInPage(t *testing.T) {
|
||||||
var position int = 17
|
var position int = 1
|
||||||
var expected string = " on page 1 in back slot 8"
|
var expected string = " on page 1 in front slot 1"
|
||||||
|
|
||||||
description := GetBinderLocationDescription(position)
|
description := GetBinderLocationDescription(position)
|
||||||
|
|
||||||
if description != expected {
|
assert(t, description, expected)
|
||||||
t.Errorf("expected %s, got %s\n", expected, description)
|
}
|
||||||
}
|
|
||||||
|
func Test_GetBinderLocationDescription_ReturnsCorrectSlotNumber_ForFirstSlotOnBackOfPage(t *testing.T) {
|
||||||
|
var position int = 10
|
||||||
|
var expected string = " on page 1 in back slot 1"
|
||||||
|
|
||||||
|
description := GetBinderLocationDescription(position)
|
||||||
|
|
||||||
|
assert(t, description, expected)
|
||||||
|
}
|
||||||
|
|
||||||
|
func Test_GetBinderLocationDescription_ReturnsCorrectSlotNumber_ForLastSlotOnBackOfPage(t *testing.T) {
|
||||||
|
var position int = 18
|
||||||
|
var expected string = " on page 1 in back slot 9"
|
||||||
|
|
||||||
|
description := GetBinderLocationDescription(position)
|
||||||
|
|
||||||
|
assert(t, description, expected)
|
||||||
|
}
|
||||||
|
|
||||||
|
func Test_GetBinderLocationDescription_ReturnsCorrectSlotNumber_ForLastSlotOnBackOfSecondPage(t *testing.T) {
|
||||||
|
var position int = 36
|
||||||
|
var expected string = " on page 2 in back slot 9"
|
||||||
|
|
||||||
|
description := GetBinderLocationDescription(position)
|
||||||
|
|
||||||
|
assert(t, description, expected)
|
||||||
}
|
}
|
||||||
|
|
|
@ -9,15 +9,10 @@ import (
|
||||||
|
|
||||||
var UnrecognizedStorageAreaTypeError error = errors.New("Unrecognized storage area type.")
|
var UnrecognizedStorageAreaTypeError error = errors.New("Unrecognized storage area type.")
|
||||||
|
|
||||||
func RemoveFromStorage(db *sql.DB, location database.CardLocation) error {
|
func RemoveFromStorage(db *sql.DB, location database.LocateCardResult) error {
|
||||||
locationType, err := database.GetStorageAreaTypeById(db, location.Id)
|
if location.StorageAreaType == database.StorageAreaTypeBinder {
|
||||||
if err != nil {
|
|
||||||
return err
|
|
||||||
}
|
|
||||||
|
|
||||||
if locationType == database.StorageAreaTypeBinder {
|
|
||||||
database.RemoveFromBinder(db, location)
|
database.RemoveFromBinder(db, location)
|
||||||
} else if locationType == database.StorageAreaTypeBox {
|
} else if location.StorageAreaType == database.StorageAreaTypeBox {
|
||||||
database.RemoveFromBox(db, location)
|
database.RemoveFromBox(db, location)
|
||||||
} else {
|
} else {
|
||||||
return UnrecognizedStorageAreaTypeError
|
return UnrecognizedStorageAreaTypeError
|
||||||
|
|
|
@ -61,7 +61,7 @@ func GetAllSearchOptions(db *sql.DB, searchCriteria SearchCriteria) (InsertSearc
|
||||||
return searchOptions, err
|
return searchOptions, err
|
||||||
}
|
}
|
||||||
|
|
||||||
func GenericSearch[pk string | int](options map[string]pk) (pk, error) {
|
func GenericSearch[pk string | int](options map[string]pk) (pk, string, error) {
|
||||||
var value pk
|
var value pk
|
||||||
|
|
||||||
cmd := exec.Command("fzf")
|
cmd := exec.Command("fzf")
|
||||||
|
@ -69,7 +69,7 @@ func GenericSearch[pk string | int](options map[string]pk) (pk, error) {
|
||||||
|
|
||||||
fzfStdin, err := cmd.StdinPipe()
|
fzfStdin, err := cmd.StdinPipe()
|
||||||
if err != nil {
|
if err != nil {
|
||||||
return value, err
|
return value, "", err
|
||||||
}
|
}
|
||||||
|
|
||||||
go func() {
|
go func() {
|
||||||
|
@ -81,10 +81,10 @@ func GenericSearch[pk string | int](options map[string]pk) (pk, error) {
|
||||||
|
|
||||||
fzfOutput, err := cmd.Output()
|
fzfOutput, err := cmd.Output()
|
||||||
if err != nil {
|
if err != nil {
|
||||||
return value, err
|
return value, "", err
|
||||||
}
|
}
|
||||||
|
|
||||||
searchResult := strings.TrimSuffix(string(fzfOutput), "\n")
|
searchResult := strings.TrimSuffix(string(fzfOutput), "\n")
|
||||||
value = options[searchResult]
|
value = options[searchResult]
|
||||||
return value, nil
|
return value, searchResult, nil
|
||||||
}
|
}
|
||||||
|
|
|
@ -2,13 +2,11 @@ package logic
|
||||||
|
|
||||||
import (
|
import (
|
||||||
"database/sql"
|
"database/sql"
|
||||||
"io"
|
|
||||||
"os"
|
|
||||||
"os/exec"
|
|
||||||
"sevenkeys/database"
|
"sevenkeys/database"
|
||||||
"strings"
|
|
||||||
)
|
)
|
||||||
|
|
||||||
|
type StorageAreaSearchOptions map[string]int
|
||||||
|
|
||||||
func CreateStorageArea(db *sql.DB, storageArea database.StorageArea) error {
|
func CreateStorageArea(db *sql.DB, storageArea database.StorageArea) error {
|
||||||
// TODO: Check if there's already a storage are with the same name
|
// TODO: Check if there's already a storage are with the same name
|
||||||
// TODO: Check if the type entered is valid
|
// TODO: Check if the type entered is valid
|
||||||
|
@ -20,46 +18,22 @@ func CreateStorageArea(db *sql.DB, storageArea database.StorageArea) error {
|
||||||
return nil
|
return nil
|
||||||
}
|
}
|
||||||
|
|
||||||
func SelectStorageArea(db *sql.DB) (database.StorageArea, error) {
|
func GetStorageAreaSearchOptions(db *sql.DB) (StorageAreaSearchOptions, error) {
|
||||||
var selectedStorageArea database.StorageArea
|
var options StorageAreaSearchOptions
|
||||||
|
|
||||||
storageAreas, err := database.GetAllStorageAreas(db)
|
storageAreas, err := database.GetAllStorageAreas(db)
|
||||||
if err != nil {
|
if err != nil {
|
||||||
return selectedStorageArea, err
|
return options, err
|
||||||
}
|
}
|
||||||
|
|
||||||
cmd := exec.Command("fzf")
|
|
||||||
cmd.Stderr = os.Stderr
|
|
||||||
|
|
||||||
fzfStdin, err := cmd.StdinPipe()
|
|
||||||
if err != nil {
|
|
||||||
return selectedStorageArea, err
|
|
||||||
}
|
|
||||||
|
|
||||||
go func() {
|
|
||||||
defer fzfStdin.Close()
|
|
||||||
for _, area := range storageAreas {
|
|
||||||
io.WriteString(fzfStdin, area.Name+"\n")
|
|
||||||
}
|
|
||||||
}()
|
|
||||||
|
|
||||||
fzfOutput, err := cmd.Output()
|
|
||||||
if err != nil {
|
|
||||||
return selectedStorageArea, err
|
|
||||||
}
|
|
||||||
|
|
||||||
key := strings.TrimSuffix(string(fzfOutput), "\n")
|
|
||||||
for _, area := range storageAreas {
|
for _, area := range storageAreas {
|
||||||
if area.Name == key {
|
options[area.Name] = area.Id
|
||||||
selectedStorageArea = area
|
|
||||||
break
|
|
||||||
}
|
|
||||||
}
|
}
|
||||||
|
|
||||||
return selectedStorageArea, nil
|
return options, nil
|
||||||
}
|
}
|
||||||
|
|
||||||
func StoreCard(db *sql.DB, cardLocation database.CardLocation) error {
|
func StoreAfterLastCard(db *sql.DB, cardLocation database.CardLocation) error {
|
||||||
lastPosition, err := database.GetLastPositionInStorageArea(db, cardLocation.StorageAreaId)
|
lastPosition, err := database.GetLastPositionInStorageArea(db, cardLocation.StorageAreaId)
|
||||||
if err != nil {
|
if err != nil {
|
||||||
return err
|
return err
|
||||||
|
@ -74,3 +48,46 @@ func StoreCard(db *sql.DB, cardLocation database.CardLocation) error {
|
||||||
|
|
||||||
return nil
|
return nil
|
||||||
}
|
}
|
||||||
|
|
||||||
|
func StoreInEmptySlot(db *sql.DB, cardLocation database.CardLocation, cardLocationId int) error {
|
||||||
|
cardLocation.Id = cardLocationId
|
||||||
|
err := database.InsertCardInExistingLocation(db, cardLocation)
|
||||||
|
if err != nil {
|
||||||
|
return err
|
||||||
|
}
|
||||||
|
|
||||||
|
return nil
|
||||||
|
}
|
||||||
|
|
||||||
|
func StoreCard(db *sql.DB, cardLocation database.CardLocation) error {
|
||||||
|
storageAreaType, err := database.GetStorageAreaTypeById(db, cardLocation.StorageAreaId)
|
||||||
|
if err != nil {
|
||||||
|
return err
|
||||||
|
}
|
||||||
|
|
||||||
|
if storageAreaType == database.StorageAreaTypeBinder {
|
||||||
|
nextEmptySlotId, err := database.GetNextEmptySlotInBinder(db, cardLocation.StorageAreaId)
|
||||||
|
|
||||||
|
if err == sql.ErrNoRows {
|
||||||
|
err = StoreAfterLastCard(db, cardLocation)
|
||||||
|
if err != nil {
|
||||||
|
return err
|
||||||
|
}
|
||||||
|
} else if err != nil {
|
||||||
|
return err
|
||||||
|
} else {
|
||||||
|
err = StoreInEmptySlot(db, cardLocation, nextEmptySlotId)
|
||||||
|
if err != nil {
|
||||||
|
return err
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
return nil
|
||||||
|
}
|
||||||
|
|
||||||
|
err = StoreAfterLastCard(db, cardLocation)
|
||||||
|
if err != nil {
|
||||||
|
return err
|
||||||
|
}
|
||||||
|
return nil
|
||||||
|
}
|
||||||
|
|
Loading…
Reference in New Issue