chirpnest/sql.go

344 lines
13 KiB
Go
Raw Normal View History

2019-05-03 05:58:36 +02:00
package main
import (
2019-05-06 16:05:43 +02:00
"errors"
2019-05-03 05:58:36 +02:00
"log"
2019-05-08 12:47:32 +02:00
"regexp"
2019-05-06 06:01:01 +02:00
"strconv"
2019-05-03 05:58:36 +02:00
)
func initDB() {
log.Println("Setting up database...")
tx, err := db.Begin()
if err != nil {
log.Fatal(err)
}
defer tx.Rollback()
_, err = tx.Exec("set foreign_key_checks = 0")
2019-05-06 05:03:12 +02:00
failOnError(err, "initDB : set foreign_key_checks = 0")
2019-05-03 05:58:36 +02:00
var name string
rows, err := db.Query("show tables")
2019-05-06 05:03:12 +02:00
failOnError(err, "initDB : show tables")
2019-05-03 05:58:36 +02:00
for rows.Next() {
err = rows.Scan(&name)
2019-05-06 05:03:12 +02:00
failOnError(err, "initDB : show tables listing")
2019-05-03 05:58:36 +02:00
_, err = tx.Exec("drop table " + name)
2019-05-06 05:03:12 +02:00
failOnError(err, "initDB : drop table "+name)
2019-05-03 05:58:36 +02:00
}
err = rows.Err()
2019-05-06 05:03:12 +02:00
failOnError(err, "initDB : show tables listing end")
2019-05-03 05:58:36 +02:00
rows.Close()
_, err = tx.Exec("set foreign_key_checks = 1")
2019-05-06 05:03:12 +02:00
failOnError(err, "initDB : set foreign_key_checks = 1")
2019-05-03 05:58:36 +02:00
err = tx.Commit()
2019-05-06 05:03:12 +02:00
failOnError(err, "initDB : commit cleanup")
2019-05-03 05:58:36 +02:00
log.Println("Database cleaned up")
2019-05-04 10:57:24 +02:00
_, err = db.Exec(`CREATE TABLE code_obj_type (
2019-05-07 13:15:25 +02:00
id SMALLINT UNSIGNED NOT NULL
2019-05-04 10:57:24 +02:00
,intl_id VARCHAR(32) NOT NULL
,name VARCHAR(80) NOT NULL
,PRIMARY KEY (id)
2019-05-06 15:48:43 +02:00
) ENGINE = InnoDB CHARSET=utf8mb4 COLLATE utf8mb4_unicode_ci;`)
2019-05-06 05:03:12 +02:00
failOnError(err, "initDB : create table code_obj_type")
2019-05-04 10:57:24 +02:00
2019-05-05 13:29:28 +02:00
_, err = db.Exec(`CREATE TABLE code_obj_sub_type (
2019-05-07 13:15:25 +02:00
id SMALLINT UNSIGNED NOT NULL
,intl_id VARCHAR(32) NOT NULL
,name VARCHAR(80) NOT NULL
2019-05-05 13:29:28 +02:00
,obj_type_id SMALLINT UNSIGNED NOT NULL
,PRIMARY KEY (id)
,FOREIGN KEY (obj_type_id) REFERENCES code_obj_type(id) ON DELETE CASCADE
2019-05-06 15:48:43 +02:00
) ENGINE = InnoDB CHARSET=utf8mb4 COLLATE utf8mb4_unicode_ci;`)
2019-05-06 05:03:12 +02:00
failOnError(err, "initDB : create table code_obj_sub_type")
2019-05-05 13:29:28 +02:00
2019-05-04 10:57:24 +02:00
_, err = db.Exec(`CREATE TABLE obj (
2019-05-06 05:09:31 +02:00
id BIGINT UNSIGNED NOT NULL AUTO_INCREMENT
,obj_type_id SMALLINT UNSIGNED NOT NULL
,obj_sub_type_id SMALLINT UNSIGNED NOT NULL
2019-05-04 10:57:24 +02:00
,PRIMARY KEY (id)
2019-05-08 12:36:29 +02:00
,FOREIGN KEY (obj_type_id) REFERENCES code_obj_type(id) ON DELETE CASCADE
,FOREIGN KEY (obj_sub_type_id) REFERENCES code_obj_sub_type(id) ON DELETE CASCADE
2019-05-06 15:48:43 +02:00
) ENGINE = InnoDB AUTO_INCREMENT = 0 CHARSET=utf8mb4 COLLATE utf8mb4_unicode_ci;`)
2019-05-06 05:03:12 +02:00
failOnError(err, "initDB : create table obj")
2019-05-04 10:57:24 +02:00
_, err = db.Exec(`CREATE TABLE obj_user (
obj_id BIGINT UNSIGNED NOT NULL
2019-05-06 05:03:12 +02:00
,telegram_id BIGINT UNSIGNED NOT NULL
2019-05-04 10:57:24 +02:00
,user_id VARCHAR(32) NOT NULL
,name VARCHAR(80) NOT NULL
,guild_id BIGINT UNSIGNED
,last_msg TIMESTAMP
,busy_until TIMESTAMP
,role ENUM('commander', 'bartender', 'squire', 'none')
,FOREIGN KEY (obj_id) REFERENCES obj(id) ON DELETE CASCADE
2019-05-06 15:48:43 +02:00
) ENGINE = InnoDB CHARSET=utf8mb4 COLLATE utf8mb4_unicode_ci;`)
2019-05-06 05:03:12 +02:00
failOnError(err, "initDB : create table obj_user")
2019-05-04 10:57:24 +02:00
_, err = db.Exec(`CREATE TABLE obj_guild (
2019-05-07 13:15:25 +02:00
obj_id BIGINT UNSIGNED NOT NULL
2019-05-04 10:57:24 +02:00
,tag VARCHAR(32) NOT NULL
,name VARCHAR(80) NOT NULL
,chat_id BIGINT NOT NULL
,deposit_chat_id BIGINT NOT NULL
2019-05-04 11:04:52 +02:00
,FOREIGN KEY (obj_id) REFERENCES obj(id) ON DELETE CASCADE
2019-05-06 15:48:43 +02:00
) ENGINE = InnoDB CHARSET=utf8mb4 COLLATE utf8mb4_unicode_ci;`)
2019-05-06 05:03:12 +02:00
failOnError(err, "initDB : create table obj_guild")
2019-05-04 10:57:24 +02:00
2019-05-07 05:12:03 +02:00
_, err = db.Exec(`CREATE TABLE obj_war (
obj_id BIGINT UNSIGNED NOT NULL AUTO_INCREMENT
,start_time TIMESTAMP NOT NULL
,end_time TIMESTAMP NOT NULL
,FOREIGN KEY (obj_id) REFERENCES obj(id) ON DELETE CASCADE
) ENGINE = InnoDB CHARSET=utf8mb4 COLLATE utf8mb4_unicode_ci;`)
failOnError(err, "initDB : create table obj_war")
2019-05-04 10:57:24 +02:00
_, err = db.Exec(`CREATE TABLE obj_msg (
obj_id BIGINT UNSIGNED NOT NULL
,msg_id BIGINT NOT NULL
,chat_id BIGINT NOT NULL
2019-05-06 07:43:15 +02:00
,user_id BIGINT NOT NULL
2019-05-04 10:57:24 +02:00
,sender_user_id BIGINT NOT NULL
,date TIMESTAMP NOT NULL
,text VARCHAR(4096) NOT NULL
,FOREIGN KEY (obj_id) REFERENCES obj(id) ON DELETE CASCADE
,UNIQUE KEY (msg_id, chat_id, sender_user_id)
2019-05-06 15:48:43 +02:00
) ENGINE = InnoDB CHARSET=utf8mb4 COLLATE utf8mb4_unicode_ci;`)
2019-05-06 05:03:12 +02:00
failOnError(err, "initDB : create table obj_msg")
2019-05-03 05:58:36 +02:00
2019-05-05 13:29:28 +02:00
_, err = db.Exec(`CREATE TABLE obj_msg_report (
2019-05-06 12:43:42 +02:00
obj_id BIGINT UNSIGNED NOT NULL
2019-05-07 05:12:03 +02:00
,war_id BIGINT UNSIGNED NOT NULL
,FOREIGN KEY (obj_id) REFERENCES obj(id) ON DELETE CASCADE
,FOREIGN KEY (war_id) REFERENCES obj(id) ON DELETE CASCADE
) ENGINE = InnoDB CHARSET=utf8mb4 COLLATE utf8mb4_unicode_ci;`)
failOnError(err, "initDB : create table obj_msg_report")
_, err = db.Exec(`CREATE TABLE obj_war_report (
obj_id BIGINT UNSIGNED NOT NULL
,user_id BIGINT UNSIGNED NOT NULL
,war_id BIGINT UNSIGNED NOT NULL
2019-05-06 12:43:42 +02:00
,attack SMALLINT UNSIGNED NOT NULL
,defense SMALLINT UNSIGNED NOT NULL
,gold SMALLINT UNSIGNED NOT NULL
2019-05-06 15:50:57 +02:00
,stock SMALLINT UNSIGNED NOT NULL
2019-05-05 13:29:28 +02:00
,exp SMALLINT UNSIGNED NOT NULL
2019-05-06 12:43:42 +02:00
,stamina TINYINT NOT NULL
,crit TINYINT NOT NULL
2019-05-05 13:29:28 +02:00
,FOREIGN KEY (obj_id) REFERENCES obj(id) ON DELETE CASCADE
2019-05-07 05:12:03 +02:00
,FOREIGN KEY (war_id) REFERENCES obj(id) ON DELETE CASCADE
,UNIQUE KEY (user_id, war_id)
2019-05-06 15:48:43 +02:00
) ENGINE = InnoDB CHARSET=utf8mb4 COLLATE utf8mb4_unicode_ci;`)
2019-05-06 05:03:12 +02:00
failOnError(err, "initDB : create table obj_msg_report")
2019-05-05 13:29:28 +02:00
2019-05-08 15:39:04 +02:00
_, err = db.Exec(`CREATE TABLE obj_auction_announce (
obj_id BIGINT UNSIGNED NOT NULL
,lot_id BIGINT UNSIGNED NOT NULL
2019-05-08 15:40:25 +02:00
,item VARCHAR(80)
2019-05-08 15:40:57 +02:00
,cond VARCHAR(32)
2019-05-08 15:40:25 +02:00
,quality VARCHAR(32)
,seller VARCHAR(32)
,buyer VARCHAR(32)
,status VARCHAR(32)
2019-05-08 15:39:04 +02:00
,end TIMESTAMP NOT NULL
,FOREIGN KEY (obj_id) REFERENCES obj(id) ON DELETE CASCADE
,UNIQUE KEY (lot_id)
) ENGINE = InnoDB CHARSET=utf8mb4 COLLATE utf8mb4_unicode_ci;`)
failOnError(err, "initDB : create table obj_auction_announce")
2019-05-07 13:15:25 +02:00
_, err = db.Exec(`CREATE TABLE msg_rules (
id SMALLINT UNSIGNED NOT NULL AUTO_INCREMENT
,prio SMALLINT NOT NULL
,descn VARCHAR(32) NOT NULL
,rule VARCHAR(4096) NOT NULL
2019-05-08 12:13:47 +02:00
,msg_type_id SMALLINT UNSIGNED NOT NULL
2019-05-07 13:15:25 +02:00
,UNIQUE KEY (id)
) ENGINE = InnoDB CHARSET=utf8mb4 COLLATE utf8mb4_unicode_ci;`)
failOnError(err, "initDB : create table msg_rules")
2019-05-04 10:57:24 +02:00
_, err = db.Exec(`INSERT INTO code_obj_type (id, intl_id, name)
2019-05-06 06:01:01 +02:00
VALUES (` + strconv.Itoa(objTypeUser) + `, "user", "User")
,(` + strconv.Itoa(objTypeGuild) + `, "guild", "Guild")
2019-05-07 05:12:03 +02:00
,(` + strconv.Itoa(objTypeMessage) + `, "msg", "Message")
,(` + strconv.Itoa(objTypeWar) + `, "war", "War")
,(` + strconv.Itoa(objTypeWarReport) + `, "war_report", "War Report")
2019-05-07 13:15:25 +02:00
,(` + strconv.Itoa(objTypeJob) + `, "job", "Job")
2019-05-07 05:12:03 +02:00
;`)
2019-05-06 05:03:12 +02:00
failOnError(err, "initDB : populate table code_obj_type")
2019-05-03 05:58:36 +02:00
2019-05-05 13:29:28 +02:00
_, err = db.Exec(`INSERT INTO code_obj_sub_type (id, intl_id, name, obj_type_id)
2019-05-07 13:15:25 +02:00
VALUES (` + strconv.Itoa(objSubTypeMessageUnknown) + `, "unknown", "Unknown", ` + strconv.Itoa(objTypeMessage) + `)
2019-05-07 05:12:03 +02:00
,(` + strconv.Itoa(objSubTypeMessageWar) + `, "war", "War report", ` + strconv.Itoa(objTypeMessage) + `)
,(` + strconv.Itoa(objSubTypeMessageMiniWar) + `, "mini_war", "Mini war reprot", ` + strconv.Itoa(objTypeMessage) + `)
,(` + strconv.Itoa(objSubTypeMessageGuildWar) + `, "guild_war", "Guilds war report", ` + strconv.Itoa(objTypeMessage) + `)
,(` + strconv.Itoa(objSubTypeMessageReport) + `, "report", "Player war report", ` + strconv.Itoa(objTypeMessage) + `)
,(` + strconv.Itoa(objSubTypeMessageGReport) + `, "g_report", "Player guilds war report", ` + strconv.Itoa(objTypeMessage) + `)
2019-05-06 07:43:15 +02:00
,(` + strconv.Itoa(objSubTypeMessageQuest) + `, "quest", "Quest result", ` + strconv.Itoa(objTypeMessage) + `)
,(` + strconv.Itoa(objSubTypeMessageFight) + `, "fight", "Fight result", ` + strconv.Itoa(objTypeMessage) + `)
,(` + strconv.Itoa(objSubTypeMessageHero) + `, "hero", "Hero summary", ` + strconv.Itoa(objTypeMessage) + `)
,(` + strconv.Itoa(objSubTypeMessageMe) + `, "me", "Hero short summary", ` + strconv.Itoa(objTypeMessage) + `)
2019-05-07 13:15:25 +02:00
,(` + strconv.Itoa(objSubTypeMessageInventory) + `, "inv", "Inventory", ` + strconv.Itoa(objTypeMessage) + `)
,(` + strconv.Itoa(objSubTypeMessagePillageInc) + `, "pillage_inc", "Pillage incoming", ` + strconv.Itoa(objTypeMessage) + `)
,(` + strconv.Itoa(objSubTypeMessageTributeInc) + `, "tribute_inc", "Request incoming", ` + strconv.Itoa(objTypeMessage) + `)
2019-05-08 16:34:47 +02:00
,(` + strconv.Itoa(objSubTypeMessagePillageAck) + `, "pillage_ack", "Pillage acknowledged", ` + strconv.Itoa(objTypeMessage) + `)
,(` + strconv.Itoa(objSubTypeMessageTributeAck) + `, "tribute_ack", "Request acknowledged", ` + strconv.Itoa(objTypeMessage) + `)
,(` + strconv.Itoa(objSubTypeMessageAuctionAnnounce) + `, "auction_announce", "Auction announce", ` + strconv.Itoa(objTypeMessage) + `);`)
2019-05-06 05:03:12 +02:00
failOnError(err, "initDB : populate table code_obj_sub_type")
2019-05-04 11:15:33 +02:00
2019-05-08 16:34:47 +02:00
_, err = db.Exec(`INSERT INTO msg_rules (prio, msg_type_id, descn, rule)
VALUES (5000, ` + strconv.Itoa(objSubTypeMessageReport) + `, "Player war report", "^(?P<Castle>[🐉🦅🐺🦈🦌🥔🌑])(?P<Guild>(\\[[A-Z]{3}\\]){0,1})(?P<User>([A-Za-z0-9 ]*)) ⚔:(?P<Attack>[0-9]+)(?P<AttackMod>\\((-|\\+)[0-9]+\\)){0,1} 🛡:(?P<Defense>[0-9]+) Lvl: (?P<Level>[0-9]+)\\nYour result on the battlefield:\\n🔥Exp: (?P<Exp>[0-9]+)\\n💰Gold: (?P<Gold>-{0,1}[0-9]+)\\n📦Stock: (?P<Stock>-{0,1}[0-9]+)(\\n)*(?P<Stamina>(🔋Stamina restored)){0,1}(\\n)*(?P<Crit>(⚡Critical strike)){0,1}(\\n)*(?s:.*)$")
2019-05-08 16:36:41 +02:00
,(5000, ` + strconv.Itoa(objSubTypeMessageAuctionAnnounce) + `, "Auction annouce", "^Lot #(?P<Lot>[0-9]+) : (?P<Item>.*)\\nSeller: (?P<Seller>.*)\\nCurrent price: (?P<Price>[0-9]+) pouch\\(es\\)\\nBuyer: (?P<Buyer>.*)\\nEnd At: (?P<End>.*)\\nStatus: (?P<Status>.*)(\\n)*(?s:.*)");`)
2019-05-08 12:37:22 +02:00
failOnError(err, "initDB : populate table msg_rules")
2019-05-08 12:13:47 +02:00
2019-05-05 13:29:28 +02:00
log.Println("Database set up")
2019-05-04 11:15:33 +02:00
}
2019-05-05 13:29:28 +02:00
func putUnprocessedMsg(m ChatWarsMessage) (int64, error) {
res, err := db.Exec(`INSERT INTO obj (obj_type_id, obj_sub_type_id)
2019-05-08 12:39:33 +02:00
VALUES (` + strconv.Itoa(objTypeMessage) + `,` + strconv.Itoa(objSubTypeMessageUnknown) + `);`)
2019-05-04 10:57:24 +02:00
if err != nil {
2019-05-06 04:56:59 +02:00
return 0, err
2019-05-04 10:57:24 +02:00
}
2019-05-05 13:29:28 +02:00
2019-05-04 10:57:24 +02:00
objId, err := res.LastInsertId()
2019-05-05 13:29:28 +02:00
if err != nil {
2019-05-06 04:56:59 +02:00
return 0, err
2019-05-05 13:29:28 +02:00
}
2019-05-04 10:57:24 +02:00
2019-05-06 07:43:15 +02:00
stmt, err := db.Prepare(`INSERT INTO obj_msg (obj_id, msg_id, chat_id, user_id, sender_user_id, date , text)
VALUES (?, ?, ?, ?, ?, FROM_UNIXTIME(?), ?);`)
2019-05-03 09:15:16 +02:00
if err != nil {
2019-05-06 04:56:59 +02:00
return 0, err
2019-05-03 09:15:16 +02:00
}
2019-05-03 18:08:38 +02:00
defer stmt.Close()
2019-05-03 09:15:16 +02:00
2019-05-06 07:43:15 +02:00
_, err = stmt.Exec(objId, m.ID64, m.ChatID64, m.UserID64, m.SenderUserID64, m.Date, m.Text)
2019-05-03 09:15:16 +02:00
if err != nil {
2019-05-06 04:56:59 +02:00
return 0, err
2019-05-05 13:29:28 +02:00
}
return objId, nil
}
func getMsg(objId int64) (ChatWarsMessage, error) {
var m ChatWarsMessage
2019-05-06 05:13:11 +02:00
stmt, err := db.Prepare(`SELECT om.msg_id, om.chat_id, om.sender_user_id, UNIX_TIMESTAMP(om.date), om.text FROM obj_msg om WHERE om.obj_id = ?`)
2019-05-05 13:29:28 +02:00
if err != nil {
2019-05-06 04:56:59 +02:00
return m, err
2019-05-05 13:29:28 +02:00
}
defer stmt.Close()
2019-05-06 04:57:20 +02:00
err = stmt.QueryRow(objId).Scan(&m.ID64, &m.ChatID64, &m.SenderUserID64, &m.Date, &m.Text)
2019-05-05 13:29:28 +02:00
if err != nil {
2019-05-06 04:56:59 +02:00
return m, err
2019-05-03 09:15:16 +02:00
}
2019-05-03 13:24:32 +02:00
2019-05-05 13:29:28 +02:00
return m, nil
2019-05-03 09:15:16 +02:00
}
2019-05-06 12:43:42 +02:00
func getObjSubTypeId(objId int64) (int64, error) {
var objSubTypeId int64
2019-05-08 12:13:47 +02:00
2019-05-06 12:43:42 +02:00
stmt, err := db.Prepare(`SELECT o.sub_type_id FROM obj o WHERE o.id = ?`)
if err != nil {
return 0, err
}
defer stmt.Close()
err = stmt.QueryRow(1).Scan(&objSubTypeId)
if err != nil {
return 0, err
}
return objSubTypeId, nil
}
func insertMsgReport(objId int64, war_date int32, atk int32, def int32, exp int32, gold int32, stock int32, crit bool, stamina bool) error {
2019-05-06 16:05:43 +02:00
objSubTypeId, err := getObjSubTypeId(objId)
if err != nil {
return err
}
2019-05-07 13:15:25 +02:00
if objSubTypeId != objSubTypeMessageUnknown {
2019-05-06 16:05:43 +02:00
return errors.New("Message is not of type Unknown")
}
2019-05-06 15:49:18 +02:00
/*
2019-05-06 15:49:55 +02:00
obj_id BIGINT UNSIGNED NOT NULL
,war_date TIMESTAMP NOT NULL
,attack SMALLINT UNSIGNED NOT NULL
,defense SMALLINT UNSIGNED NOT NULL
,gold SMALLINT UNSIGNED NOT NULL
,stock MALLINT UNSIGNED NOT NULL
,exp SMALLINT UNSIGNED NOT NULL
,stamina TINYINT NOT NULL
,crit TINYINT NOT NULL
stmt, err := db.Prepare(`INSERT INTO obj_msg_report (obj_id, war_date, attack, defense, gold, stock, exp, stamina, crit)
VALUES (?, ?, ?, ?, ?, ?, ?, ?, ?FROM_UNIXTIME(?), ?);`)
if err != nil {
return err
}
defer stmt.Close()
_, err = stmt.Exec(objId, m.ID64, m.ChatID64, m.UserID64, m.SenderUserID64, m.Date, m.Text)
if err != nil {
return err
}
2019-05-06 15:49:18 +02:00
*/
2019-05-06 12:43:42 +02:00
return nil
}
2019-05-08 12:13:47 +02:00
2019-05-08 13:12:30 +02:00
func loadMsgParsingRules() (m map[int]MessageParsingRule, err error) {
2019-05-08 12:13:47 +02:00
var (
id int32
priority int32
descn string
rule string
msgTypeID int32
)
2019-05-08 12:47:32 +02:00
log.Println("Loading message parsing rules...")
2019-05-08 13:12:30 +02:00
m = make(map[int]MessageParsingRule)
2019-05-08 12:13:47 +02:00
count := int(0)
2019-05-08 13:00:43 +02:00
defer func() {
if rec := recover(); rec != nil {
2019-05-08 13:16:38 +02:00
log.Println("Error parsing rules : ", rec)
2019-05-08 13:14:03 +02:00
err = errors.New("panic")
2019-05-08 13:00:43 +02:00
}
}()
2019-05-08 12:37:53 +02:00
rules, err := db.Query(`SELECT r.id, r.prio, r.descn, r.rule, r.msg_type_id FROM msg_rules r ORDER BY r.prio DESC;`)
2019-05-08 12:13:47 +02:00
if err != nil {
return m, err
}
defer rules.Close()
for rules.Next() {
2019-05-08 12:17:07 +02:00
err = rules.Scan(&id, &priority, &descn, &rule, &msgTypeID)
2019-05-08 12:13:47 +02:00
if err != nil {
return m, err
}
2019-05-08 12:17:07 +02:00
i := new(MessageParsingRule)
i.ID = id
i.Priority = priority
i.Description = descn
i.Rule = rule
i.MsgTypeID = msgTypeID
2019-05-08 13:13:19 +02:00
i.re = regexp.MustCompile(rule)
2019-05-08 12:17:07 +02:00
m[count] = *i
2019-05-08 13:24:12 +02:00
log.Printf("New rule : %s\n", rule)
2019-05-08 12:13:47 +02:00
count++
}
return m, nil
}