diff --git a/sevenkeys/.gitignore b/sevenkeys/.gitignore new file mode 100644 index 0000000..4fb88ac --- /dev/null +++ b/sevenkeys/.gitignore @@ -0,0 +1 @@ +cmd/database/config.json diff --git a/sevenkeys/Makefile b/sevenkeys/Makefile new file mode 100644 index 0000000..4b09c92 --- /dev/null +++ b/sevenkeys/Makefile @@ -0,0 +1,2 @@ +dbup: + go run cmd/database/main.go diff --git a/sevenkeys/cmd/database/main.go b/sevenkeys/cmd/database/main.go new file mode 100644 index 0000000..090be1d --- /dev/null +++ b/sevenkeys/cmd/database/main.go @@ -0,0 +1,32 @@ +package main + +import ( + "encoding/json" + "log" + "os" + + "sevenkeys/database" + + "github.com/go-sql-driver/mysql" +) + +func readConfigFromFile(filename string) mysql.Config { + bytes, err := os.ReadFile(filename) + if err != nil { + log.Fatal(err) + } + + var config mysql.Config + err = json.Unmarshal(bytes, &config) + if err != nil { + log.Fatal(err) + } + + return config +} + +func main() { + config := readConfigFromFile("config.json") + db := database.GetDatabase(config) + database.CreateDatabaseSchema(db) +} diff --git a/sevenkeys/config.example.json b/sevenkeys/config.example.json new file mode 100644 index 0000000..a846ff6 --- /dev/null +++ b/sevenkeys/config.example.json @@ -0,0 +1,8 @@ +{ + "User": "", + "Passwd": "", + "Net": "tcp", + "Addr": "127.0.0.1:3306", + "DBName": "", + "AllowNativePasswords": true +} diff --git a/sevenkeys/config.json b/sevenkeys/config.json new file mode 100644 index 0000000..fbf1e9e --- /dev/null +++ b/sevenkeys/config.json @@ -0,0 +1,8 @@ +{ + "User": "root", + "Passwd": "o7MS6CIn660jIApSP", + "Net": "tcp", + "Addr": "127.0.0.1:3306", + "DBName": "sevenkeys", + "AllowNativePasswords": true +} diff --git a/sevenkeys/database/setup.go b/sevenkeys/database/setup.go new file mode 100644 index 0000000..55ef9fc --- /dev/null +++ b/sevenkeys/database/setup.go @@ -0,0 +1,283 @@ +package database + +import ( + "database/sql" + "log" + + "github.com/go-sql-driver/mysql" +) + +var db *sql.DB + +func GetDatabase(config mysql.Config) *sql.DB { + db, err := sql.Open("mysql", config.FormatDSN()) + + if err != nil { + log.Fatal(err) + } + if err = db.Ping(); err != nil { + log.Fatal(err) + } + + return db +} + +func createGamepieceTable(db *sql.DB) { + query := `CREATE TABLE IF NOT EXISTS Gamepiece ( + Id INT AUTO_INCREMENT PRIMARY KEY, + ArenaId INT NULL, + ScryfallId VARCHAR(36) NOT NULL, + OracleId VARCHAR(36) NOT NULL, + Name VARCHAR(141) NOT NULL, + Layout ENUM("normal", + "split", + "flip", + "transform", + "modal_dfc", + "meld", + "leveler", + "class", + "case", + "saga", + "adventure", + "mutate", + "prototype", + "battle", + "planar", + "scheme", + "vanguard", + "token", + "double_faced_token", + "emblem", + "augment", + "host", + "art_series", + "reversible_card") NOT NULL, + ManaCost VARCHAR(8) NOT NULL, + ManaValue FLOAT(7,2) NOT NULL, + TypeLine VARCHAR(50) NOT NULL, + OracleText VARCHAR(800) NOT NULL, + Power VARCHAR(5) NULL, + Toughness VARCHAR(5) NULL, + ReserveList BOOLEAN NOT NULL + );` + + _, err := db.Exec(query) + if err != nil { + log.Fatal(err) + } +} + +func createColorTable(db *sql.DB) { + query := `CREATE TABLE IF NOT EXISTS Color ( + Id INT AUTO_INCREMENT PRIMARY KEY, + Name VARCHAR(5) NOT NULL, + Abbreviation VARCHAR(1) NOT NULL + );` + + _, err := db.Exec(query) + if err != nil { + log.Fatal(err) + } +} + +func populateColorTable(db *sql.DB) { + query := `INSERT INTO Color (Name, Abbreviation) VALUES (?, ?);` + + insert, err := db.Prepare(query) + defer insert.Close() + if err != nil { + log.Fatal(err) + } + + colors := map[string]string{ + "White": "W", + "Blue": "U", + "Black": "B", + "Red": "R", + "Green": "G", + } + for name, abbrev := range colors { + result, err := insert.Exec(name, abbrev) + rowsAffected, err := result.RowsAffected() + if err != nil || rowsAffected != 1 { + log.Fatal(err) + } + } +} + +func createGamepieceColorTable(db *sql.DB) { + query := `CREATE TABLE IF NOT EXISTS GamepieceColor ( + ColorId INT, + GamepieceId INT, + PRIMARY KEY (ColorId, GamepieceId), + FOREIGN KEY (ColorId) REFERENCES Color(Id), + FOREIGN KEY (GamepieceId) REFERENCES Gamepiece(Id) + );` + + _, err := db.Exec(query) + if err != nil { + log.Fatal(err) + } +} + +func createGamepieceColorIdentityTable(db *sql.DB) { + query := `CREATE TABLE IF NOT EXISTS GamepieceColorIdentity ( + ColorId INT, + GamepieceId INT, + PRIMARY KEY (ColorId, GamepieceId), + FOREIGN KEY (ColorId) REFERENCES Color(Id), + FOREIGN KEY (GamepieceId) REFERENCES Gamepiece(Id) + );` + + _, err := db.Exec(query) + if err != nil { + log.Fatal(err) + } +} + +func createGamepieceColorIndicatorTable(db *sql.DB) { + query := `CREATE TABLE IF NOT EXISTS GamepieceColorIndicator ( + ColorId INT, + GamepieceId INT, + PRIMARY KEY (ColorId, GamepieceId), + FOREIGN KEY (ColorId) REFERENCES Color(Id), + FOREIGN KEY (GamepieceId) REFERENCES Gamepiece(Id) + );` + + _, err := db.Exec(query) + if err != nil { + log.Fatal(err) + } +} + +func createKeywordTable(db *sql.DB) { + query := `CREATE TABLE IF NOT EXISTS Keyword ( + Id INT AUTO_INCREMENT PRIMARY KEY, + Name VARCHAR(20) NOT NULL + );` + + _, err := db.Exec(query) + if err != nil { + log.Fatal(err) + } +} + +func createGamepieceKeywordTable(db *sql.DB) { + query := `CREATE TABLE IF NOT EXISTS GamepieceKeyword ( + GamepieceId INT NOT NULL, + KeywordId INT NOT NULL, + PRIMARY KEY (GamepieceId, KeywordId), + FOREIGN KEY (GamepieceId) REFERENCES Gamepiece(Id), + FOREIGN KEY (KeywordId) REFERENCES Keyword(Id) + );` + + _, err := db.Exec(query) + if err != nil { + log.Fatal(err) + } +} + +func createFormatTable(db *sql.DB) { + query := `CREATE TABLE IF NOT EXISTS Format ( + Id INT AUTO_INCREMENT PRIMARY KEY, + Name VARCHAR(50) + );` + + _, err := db.Exec(query) + if err != nil { + log.Fatal(err) + } +} + +func createGamepieceFormatLegalityTable(db *sql.DB) { + query := `CREATE TABLE IF NOT EXISTS GamepieceFormatLegality ( + GamepieceId INT NOT NULL, + FormatId INT NOT NULL, + PRIMARY KEY (GamepieceId, FormatId), + FOREIGN KEY (GamepieceId) REFERENCES Gamepiece(Id), + FOREIGN KEY (FormatId) REFERENCES Format(Id), + Legality ENUM("legal", "not_legal", "restricted", "banned") NOT NULL + );` + + _, err := db.Exec(query) + if err != nil { + log.Fatal(err) + } +} + +func createSetTable(db *sql.DB) { + query := `CREATE TABLE IF NOT EXISTS ExpansionSet ( + Id INT AUTO_INCREMENT PRIMARY KEY, + SetCode VARCHAR(4) NOT NULL, + Name VARCHAR(40) NOT NULL, + Digital BOOLEAN NOT NULL + );` + + _, err := db.Exec(query) + if err != nil { + log.Fatal(err) + } +} + +func createArtistTable(db *sql.DB) { + query := `CREATE TABLE IF NOT EXISTS Artist ( + Id INT AUTO_INCREMENT PRIMARY KEY, + ScryfallId VARCHAR(36) NOT NULL, + Name VARCHAR(100) NOT NULL + );` + + _, err := db.Exec(query) + if err != nil { + log.Fatal(err) + } +} + +func createCardPrintingTable(db *sql.DB) { + query := `CREATE TABLE IF NOT EXISTS CardPrinting ( + Id INT AUTO_INCREMENT PRIMARY KEY, + GamepieceId INT, + FOREIGN KEY (GamepieceId) REFERENCES Gamepiece(Id), + Language VARCHAR(3) NOT NULL, + ReleasedAt DATETIME NOT NULL, + Reprint BOOLEAN NOT NULL, + ExpansionSetId INT NOT NULL, + FOREIGN KEY (ExpansionSetId) REFERENCES ExpansionSet(Id), + CollectorNumber VARCHAR(10) NOT NULL, + Rarity ENUM("common", "uncommon", "rare", "special", "mythic", "bonus") NOT NULL, + ArtistId INT NULL, + FOREIGN KEY (ArtistId) REFERENCES Artist(Id), + BorderColor ENUM("black", "white", "borderless", "silver", "gold") NOT NULL, + Frame ENUM("1993", "1997", "2003", "2015", "future") NOT NULL, + FullArt BOOLEAN NOT NULL, + Textless BOOLEAN NOT NULL, + StorySpotlight BOOLEAN NOT NULL, + FlavorName VARCHAR(40) NULL, + FlavorText VARCHAR(300) NULL, + DigitalOnly BOOLEAN NOT NULL, + Variation BOOLEAN NOT NULL, + VariationId VARCHAR(36) NULL, + SecurityStamp ENUM("oval", "triangle", "acorn", "circle", "arena", "heart") NULL + );` + + _, err := db.Exec(query) + if err != nil { + log.Fatal(err) + } +} + +func CreateDatabaseSchema(db *sql.DB) { + createGamepieceTable(db) + createColorTable(db) + populateColorTable(db) + createGamepieceColorTable(db) + createGamepieceColorIdentityTable(db) + createGamepieceColorIndicatorTable(db) + createKeywordTable(db) + createGamepieceKeywordTable(db) + createFormatTable(db) + createGamepieceFormatLegalityTable(db) + createSetTable(db) + createArtistTable(db) + createCardPrintingTable(db) +} diff --git a/sevenkeys/go.mod b/sevenkeys/go.mod index 333aaf6..b8dc8a5 100644 --- a/sevenkeys/go.mod +++ b/sevenkeys/go.mod @@ -1,8 +1,7 @@ -module main +module sevenkeys go 1.22.1 -require ( - filippo.io/edwards25519 v1.1.0 // indirect - github.com/go-sql-driver/mysql v1.8.1 // indirect -) +require github.com/go-sql-driver/mysql v1.8.1 + +require filippo.io/edwards25519 v1.1.0 // indirect diff --git a/sevenkeys/setup.sql b/sevenkeys/setup.sql index 354609e..3785b84 100644 --- a/sevenkeys/setup.sql +++ b/sevenkeys/setup.sql @@ -1,5 +1,141 @@ USE DATABASE sevenkeys; -CREATE TABLE IF NOT EXISTS CardPrinting; +CREATE TABLE IF NOT EXISTS Gamepiece ( + Id INT AUTO_INCREMENT PRIMARY KEY, + ArenaId INT NULL, + ScryfallId VARCHAR(36) NOT NULL, + OracleId VARCHAR(36) NOT NULL, + Name VARCHAR(141) NOT NULL, + Layout ENUM("normal", + "split", + "flip", + "transform", + "modal_dfc", + "meld", + "leveler", + "class", + "case", + "saga", + "adventure", + "mutate", + "prototype", + "battle", + "planar", + "scheme", + "vanguard", + "token", + "double_faced_token", + "emblem", + "augment", + "host", + "art_series", + "reversible_card") NOT NULL, + ManaCost VARCHAR(8) NOT NULL, + ManaValue FLOAT(7,2) NOT NULL, + TypeLine VARCHAR(50) NOT NULL, + OracleText VARCHAR(800) NOT NULL, + Power VARCHAR(5) NULL, + Toughness VARCHAR(5) NULL, + ReserveList BOOLEAN NOT NULL, +); -CREATE TABLE IF NOT EXISTS Gamepiece; +CREATE TABLE IF NOT EXISTS Color ( + Id INT AUTO_INCREMENT PRIMARY KEY, + Name VARCHAR(5) NOT NULL, + Abbreviation VARCHAR(1) NOT NULL +); +INSERT INTO Color (Name, Abbreviation) VALUES ("White", "W"); +INSERT INTO Color (Name, Abbreviation) VALUES ("Blue", "U"); +INSERT INTO Color (Name, Abbreviation) VALUES ("Black", "B"); +INSERT INTO Color (Name, Abbreviation) VALUES ("Red", "R"); +INSERT INTO Color (Name, Abbreviation) VALUES ("Green", "G"); + +CREATE TABLE IF NOT EXISTS GamepieceColor ( + ColorId INT, + GamepieceId INT, + PRIMARY KEY (ColorId, GamepieceId), + FOREIGN KEY (ColorId) REFERENCES Color(Id), + FOREIGN KEY (GamepieceId) REFERENCES Gamepiece(Id) +); + +CREATE TABLE IF NOT EXISTS GamepieceColorIdentity ( + ColorId INT, + GamepieceId INT, + PRIMARY KEY (ColorId, GamepieceId), + FOREIGN KEY (ColorId) REFERENCES Color(Id), + FOREIGN KEY (GamepieceId) REFERENCES Gamepiece(Id) +); + +CREATE TABLE IF NOT EXISTS GamepieceColorIndicator ( + ColorId INT, + GamepieceId INT, + PRIMARY KEY (ColorId, GamepieceId), + FOREIGN KEY (ColorId) REFERENCES Color(Id), + FOREIGN KEY (GamepieceId) REFERENCES Gamepiece(Id) +); + +CREATE TABLE IF NOT EXISTS Keyword ( + Id INT AUTO_INCREMENT PRIMARY KEY, + Name VARCHAR(20) NOT NULL +); + +CREATE TABLE IF NOT EXISTS GamepieceKeyword ( + GamepieceId INT NOT NULL, + KeywordId INT NOT NULL, + PRIMARY KEY (GamepieceId, KeywordId), + FOREIGN KEY (GamepieceId) REFERENCES Gamepiece(Id), + FOREIGN KEY (KeywordId) REFERENCES Keyword(Id) +); + +CREATE TABLE IF NOT EXISTS Format ( + Id INT AUTO_INCREMENT PRIMARY KEY, + Name VARCHAR(50) +); + +CREATE TABLE IF NOT EXISTS GamepieceFormatLegality ( + GamepieceId INT NOT NULL, + FormatId INT NOT NULL, + PRIMARY KEY (GamepieceId, FormatId), + FOREIGN KEY (GamepieceId) REFERENCES Gamepiece(Id), + FOREIGN KEY (FormatId) REFERENCES Format(Id), + Legality ENUM("legal", "not_legal", "restricted", "banned") NOT NULL +); + +CREATE TABLE IF NOT EXISTS ExpansionSet ( + Id INT AUTO_INCREMENT NOT NULL, + SetCode VARCHAR(4) NOT NULL, + Name VARCHAR(40) NOT NULL, + Digital BOOLEAN NOT NULL, +); + +CREATE TABLE IF NOT EXISTS Artist ( + Id INT AUTO_INCREMENT NOT NULL, + ScryfallId VARCHAR(36) NOT NULL, + Name VARCHAR(100) NOT NULL +); + +CREATE TABLE IF NOT EXISTS CardPrinting ( + Id INT AUTO_INCREMENT NOT NULL, + GamepieceId INT, + FOREIGN KEY (GamepieceId) REFERENCES Gamepiece(Id), + Language VARCHAR(3) NOT NULL, + ReleasedAt DATETIME NOT NULL, + Reprint BOOLEAN NOT NULL, + ExpansionSetId INT NOT NULL, + FOREIGN KEY (SetId) REFERENCES ExpansionSet(Id), + CollectorNumber VARCHAR(10) NOT NULL, + Rarity ENUM("common", "uncommon", "rare", "special", "mythic", "bonus") NOT NULL, + ArtistId INT NULL, + FOREIGN KEY (ArtistId) REFERENCES Artist(Id), + BorderColor ENUM("black", "white", "borderless", "silver", "gold") NOT NULL, + Frame ENUM("1993", "1997", "2003", "2015", "future") NOT NULL, + FullArt BOOLEAN NOT NULL, + Textless BOOLEAN NOT NULL, + StorySpotlight BOOLEAN NOT NULL, + FlavorName VARCHAR(40) NULL, + FlavorText VARCHAR(300) NULL, + DigitalOnly BOOLEAN NOT NULL, + Variation BOOLEAN NOT NULL, + VariationId VARCHAR(36) NULL, + SecurityStamp ENUM("oval", "triangle", "acorn", "circle", "arena", "heart") NULL, +);