Skip to content

Instantly share code, notes, and snippets.

@1lann
Created May 26, 2016 13:31
Show Gist options
  • Save 1lann/1acb1df4b0c511019fd447872a14bc7a to your computer and use it in GitHub Desktop.
Save 1lann/1acb1df4b0c511019fd447872a14bc7a to your computer and use it in GitHub Desktop.
package main
import (
"database/sql"
"encoding/json"
"fmt"
"os"
_ "github.com/mattn/go-sqlite3"
)
type HeroData []Hero
type Hero struct {
ID string `json:"id"`
Attributeid string `json:"attributeid"`
Name string `json:"name"`
Title string `json:"title"`
Description string `json:"description"`
Icon string `json:"icon"`
Role string `json:"role"`
Type string `json:"type"`
Gender string `json:"gender"`
Franchise string `json:"franchise"`
Difficulty string `json:"difficulty"`
Ratings struct {
Damage float64 `json:"damage"`
Utility float64 `json:"utility"`
Survivability float64 `json:"survivability"`
Complexity float64 `json:"complexity"`
} `json:"ratings"`
ReleaseDate string `json:"releaseDate"`
Stats map[string]Stat `json:"stats"`
Abilities map[string][]struct {
ID string `json:"id"`
Icon string `json:"icon"`
Name string `json:"name"`
Description string `json:"description"`
Cooldown float64 `json:"cooldown"`
Shortcut string `json:"shortcut,omitempty"`
Heroic bool `json:"heroic,omitempty"`
Trait bool `json:"trait,omitempty"`
Mount bool `json:"mount,omitempty"`
} `json:"abilities"`
Talents struct {
Num1 []Talent `json:"1"`
Num4 []Talent `json:"4"`
Num7 []Talent `json:"7"`
Num10 []Talent `json:"10"`
Num13 []Talent `json:"13"`
Num16 []Talent `json:"16"`
Num20 []Talent `json:"20"`
} `json:"talents"`
}
type Talent struct {
ID string `json:"id"`
Name string `json:"name"`
Description string `json:"description"`
Icon string `json:"icon"`
Cooldown float64 `json:"cooldown"`
Prerequisite string `json:"prerequisite"`
}
type Stat struct {
Hp float64 `json:"hp"`
HpPerLevel float64 `json:"hpPerLevel"`
HpRegen float64 `json:"hpRegen"`
HpRegenPerLevel float64 `json:"hpRegenPerLevel"`
Mana float64 `json:"mana"`
ManaPerLevel float64 `json:"manaPerLevel"`
ManaRegen float64 `json:"manaRegen"`
ManaRegenPerLevel float64 `json:"manaRegenPerLevel"`
}
var db *sql.DB
var talentStmt *sql.Stmt
var heroStmt *sql.Stmt
var dupTalent = make(map[string]int64)
func exec(str string) {
_, err := db.Exec(str)
if err != nil {
panic(err)
}
}
func createTables() {
exec(`DROP TABLE IF EXISTS Heroes`)
exec(`DROP TABLE IF EXISTS Class`)
exec(`DROP TABLE IF EXISTS Talents`)
exec(`DROP TABLE IF EXISTS Match`)
exec(`DROP TABLE IF EXISTS Player`)
exec(`DROP TABLE IF EXISTS Team`)
exec(`DROP TABLE IF EXISTS Class`)
exec(`DROP TABLE IF EXISTS HeroTalent`)
fmt.Println("dropped")
exec(`
CREATE TABLE Heroes
(HeroName VARCHAR(16) PRIMARY KEY,
Health INTEGER,
Mana INTEGER,
HPRegen FLOAT,
ManaRegen FLOAT,
HPPerLevel INTEGER,
HPRegenPerLevel INTEGER,
ClassName VARCHAR(14),
QSkill VARCHAR(30),
WSkill VARCHAR(30),
ESkill VARCHAR(30),
RSkill VARCHAR(30),
FOREIGN KEY(ClassName) REFERENCES Class(ClassName))
`)
exec(`
CREATE TABLE Class
(ClassName VARCHAR(14) PRIMARY KEY)
`)
exec(`
CREATE TABLE Talents
(TalentID INTEGER PRIMARY KEY,
TalentName VARCHAR(30),
Level INTEGER)
`)
exec(`
CREATE TABLE HeroTalent
(HeroTalentID INTEGER PRIMARY KEY,
TalentID INTEGER,
HeroName VARCHAR(16),
FOREIGN KEY (HeroName) REFERENCES Heroes(HeroName),
FOREIGN KEY (TalentID) REFERENCES Talents(TalentID))
`)
}
func (h Hero) ability(key string) string {
for _, aList := range h.Abilities {
for _, ability := range aList {
if ability.Shortcut == key {
return ability.Name
}
}
}
return ""
}
func insertHeroes(decoded HeroData) {
stmt, err := db.Prepare(`
INSERT INTO Heroes (HeroName, Health, Mana, HPRegen, ManaRegen, ` +
`HPPerLevel, HPRegenPerLevel, ClassName, QSkill, WSkill, ESkill, RSkill)
VALUES (?, ?, ?, ?, ?, ?, ?, ?, ?, ?, ?, ?)
`)
if err != nil {
panic(err)
}
defer stmt.Close()
for _, hero := range decoded {
var stat Stat
for _, stat = range hero.Stats {
break
}
_, err := stmt.Exec(hero.Name, stat.Hp, stat.Mana, stat.HpRegen,
stat.ManaRegen, stat.HpPerLevel, stat.HpRegenPerLevel, hero.Role,
hero.ability("Q"), hero.ability("W"), hero.ability("E"),
hero.ability("R"))
if err != nil {
panic(err)
}
}
fmt.Println("inserted heroes")
}
func insertHeroTalents(name string, level int, talents []Talent) {
for _, talent := range talents {
var err error
id, found := dupTalent[talent.Name]
if !found {
var res sql.Result
res, err = talentStmt.Exec(talent.Name, level)
if err != nil {
panic(err)
}
id, err = res.LastInsertId()
if err != nil {
panic(err)
}
dupTalent[talent.Name] = id
}
_, err = heroStmt.Exec(id, name)
if err != nil {
panic(err)
}
}
}
func insertTalents(decoded HeroData) {
var err error
talentStmt, err = db.Prepare(`
INSERT INTO Talents(TalentName, Level) VALUES (?, ?)
`)
if err != nil {
panic(err)
}
defer talentStmt.Close()
heroStmt, err = db.Prepare(`
INSERT INTO HeroTalent(TalentID, HeroName) VALUES (?, ?)
`)
if err != nil {
panic(err)
}
defer heroStmt.Close()
for _, hero := range decoded {
insertHeroTalents(hero.Name, 1, hero.Talents.Num1)
insertHeroTalents(hero.Name, 4, hero.Talents.Num4)
insertHeroTalents(hero.Name, 7, hero.Talents.Num7)
insertHeroTalents(hero.Name, 10, hero.Talents.Num10)
insertHeroTalents(hero.Name, 13, hero.Talents.Num13)
insertHeroTalents(hero.Name, 16, hero.Talents.Num16)
insertHeroTalents(hero.Name, 20, hero.Talents.Num20)
}
fmt.Println("inserted talents")
}
func main() {
var err error
db, err = sql.Open("sqlite3", "./heroes.db")
if err != nil {
panic(err)
}
defer db.Close()
createTables()
file, err := os.Open("heroes.json")
if err != nil {
panic(err)
}
rd := json.NewDecoder(file)
var decoded HeroData
err = rd.Decode(&decoded)
if err != nil {
panic(err)
}
insertHeroes(decoded)
insertTalents(decoded)
fmt.Println("finished!")
}
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment