added incremental update using max(date) on existing tables
This commit is contained in:
parent
6936f7cab7
commit
4c58ca76d2
@ -15,6 +15,7 @@ func main() {
|
|||||||
var cr coronafana.Coronafana
|
var cr coronafana.Coronafana
|
||||||
|
|
||||||
cfg.GetConfig()
|
cfg.GetConfig()
|
||||||
|
|
||||||
cr, err := coronafana.GetData(cfg)
|
cr, err := coronafana.GetData(cfg)
|
||||||
if err != nil {
|
if err != nil {
|
||||||
log.Fatalln(err)
|
log.Fatalln(err)
|
||||||
@ -30,6 +31,11 @@ func main() {
|
|||||||
log.Fatalln(err)
|
log.Fatalln(err)
|
||||||
}
|
}
|
||||||
|
|
||||||
|
err = cr.GetMaxDates(cfg, *db)
|
||||||
|
if err != nil {
|
||||||
|
log.Fatalln(err)
|
||||||
|
}
|
||||||
|
|
||||||
// Processes data for 'Global'
|
// Processes data for 'Global'
|
||||||
_, err = db.Exec(cfg.DbSchemaGlobal)
|
_, err = db.Exec(cfg.DbSchemaGlobal)
|
||||||
if err != nil {
|
if err != nil {
|
||||||
@ -46,8 +52,10 @@ func main() {
|
|||||||
if err != nil {
|
if err != nil {
|
||||||
log.Fatalln(err)
|
log.Fatalln(err)
|
||||||
}
|
}
|
||||||
|
|
||||||
err = cr.InsertPaysData(cfg, *db)
|
err = cr.InsertPaysData(cfg, *db)
|
||||||
if err != nil {
|
if err != nil {
|
||||||
log.Fatalln(err)
|
log.Fatalln(err)
|
||||||
}
|
}
|
||||||
|
|
||||||
}
|
}
|
||||||
|
@ -13,7 +13,7 @@ func (config *Config) GetConfig() (err error) {
|
|||||||
|
|
||||||
flag.Usage = utils.Usage
|
flag.Usage = utils.Usage
|
||||||
|
|
||||||
flag.StringVar(&configfile, "configfile", "coronafana.ini", "config file to use with coronafana section")
|
flag.StringVar(&configfile, "configfile", "coronafana.ini", "Config file to use with coronafana section")
|
||||||
flag.Parse()
|
flag.Parse()
|
||||||
|
|
||||||
cfg, err := ini.Load(configfile)
|
cfg, err := ini.Load(configfile)
|
||||||
@ -21,38 +21,81 @@ func (config *Config) GetConfig() (err error) {
|
|||||||
return
|
return
|
||||||
}
|
}
|
||||||
|
|
||||||
coronafanasection := cfg.Section("coronafana")
|
*config = Config{
|
||||||
|
DbHostname: "localhost",
|
||||||
|
DbName: "database",
|
||||||
|
DbUsername: "username",
|
||||||
|
DbPassword: "password",
|
||||||
|
DbTable: "corona",
|
||||||
|
CoronaURL: "https://coronavirus.politologue.com/data/coronavirus/coronacsv.aspx?format=json"}
|
||||||
|
|
||||||
config.DbHostname = coronafanasection.Key("db_hostname").MustString("localhost")
|
err = cfg.Section("coronafana").MapTo(config)
|
||||||
config.DbName = coronafanasection.Key("db_name").MustString("database")
|
if err != nil {
|
||||||
config.DbUsername = coronafanasection.Key("db_username").MustString("username")
|
return
|
||||||
config.DbPassword = coronafanasection.Key("db_password").MustString("password")
|
}
|
||||||
config.DbTable = coronafanasection.Key("db_table").MustString("corona")
|
|
||||||
config.Corona.URL = coronafanasection.Key("corona_url").MustString("")
|
|
||||||
|
|
||||||
config.DbSchemaGlobal = "CREATE TABLE IF NOT EXISTS coronaglobaldata (`id` int(8) NOT NULL AUTO_INCREMENT, `date` datetime NOT NULL, `infection` int(8) DEFAULT NULL, `deces` int(8) DEFAULT NULL, `guerisons` varchar(50) DEFAULT NULL, `tauxdeces` float(10) DEFAULT NULL, `tauxguerison` float(10) DEFAULT NULL, `tauxinfection` float(10) DEFAULT NULL, PRIMARY KEY (`id`), UNIQUE KEY `date` (`date`) USING BTREE) ENGINE=InnoDB DEFAULT CHARSET=utf8;"
|
config.DbSchemaGlobal = `
|
||||||
|
CREATE TABLE IF NOT EXISTS coronaglobaldata
|
||||||
|
(
|
||||||
|
id int(8) NOT NULL AUTO_INCREMENT,
|
||||||
|
date datetime NOT NULL,
|
||||||
|
infection int(8) DEFAULT NULL,
|
||||||
|
deces int(8) DEFAULT NULL,
|
||||||
|
guerisons varchar(50) DEFAULT NULL,
|
||||||
|
tauxdeces float(10) DEFAULT NULL,
|
||||||
|
tauxguerison float(10) DEFAULT NULL,
|
||||||
|
tauxinfection float(10) DEFAULT NULL,
|
||||||
|
PRIMARY KEY (id),
|
||||||
|
UNIQUE KEY date (date) USING BTREE
|
||||||
|
) ENGINE=InnoDB DEFAULT CHARSET=utf8;
|
||||||
|
`
|
||||||
|
|
||||||
config.DbInsertGlobal = "INSERT INTO coronaglobaldata (date, infection, deces, guerisons, tauxdeces, tauxguerison, tauxinfection) VALUES (:date, :infection, :deces, :guerisons, :tauxdeces, :tauxguerison, :tauxinfection) ON DUPLICATE KEY UPDATE date=:date,infection=:infection, deces=:deces, guerisons=:guerisons, tauxdeces=:tauxdeces, tauxguerison=:tauxguerison, tauxinfection=:tauxinfection;"
|
config.DbInsertGlobal = `
|
||||||
|
INSERT INTO coronaglobaldata (date, infection, deces, guerisons, tauxdeces, tauxguerison, tauxinfection)
|
||||||
|
VALUES (:date, :infection, :deces, :guerisons, :tauxdeces, :tauxguerison, :tauxinfection)
|
||||||
|
ON DUPLICATE KEY UPDATE date=:date,infection=:infection, deces=:deces, guerisons=:guerisons, tauxdeces=:tauxdeces, tauxguerison=:tauxguerison, tauxinfection=:tauxinfection;
|
||||||
|
`
|
||||||
|
|
||||||
config.DbSchemaPays = "CREATE TABLE IF NOT EXISTS coronapaysdata (`id` int(8) NOT NULL AUTO_INCREMENT, `date` datetime NOT NULL, `pays` varchar(50) NOT NULL, `infection` int(8) DEFAULT NULL, `deces` int(8) DEFAULT NULL, `guerisons` varchar(50) DEFAULT NULL, `tauxdeces` float(10) DEFAULT NULL, `tauxguerison` float(10) DEFAULT NULL, `tauxinfection` float(10) DEFAULT NULL, PRIMARY KEY (`id`), UNIQUE KEY `date` (`date`,`pays`) USING BTREE) ENGINE=InnoDB DEFAULT CHARSET=utf8;"
|
config.DbMaxDateGlobal = `SELECT max(date) FROM coronaglobaldata;`
|
||||||
|
|
||||||
config.DbInsertPays = "INSERT INTO coronapaysdata (date, pays, infection, deces, guerisons, tauxdeces, tauxguerison, tauxinfection) VALUES (:date, :pays, :infection, :deces, :guerisons, :tauxdeces, :tauxguerison, :tauxinfection) ON DUPLICATE KEY UPDATE date=:date, pays=:pays,infection=:infection, deces=:deces, guerisons=:guerisons, tauxdeces=:tauxdeces, tauxguerison=:tauxguerison, tauxinfection=:tauxinfection;"
|
config.DbSchemaPays = `
|
||||||
|
CREATE TABLE IF NOT EXISTS coronapaysdata
|
||||||
|
(
|
||||||
|
id int(8) NOT NULL AUTO_INCREMENT,
|
||||||
|
date datetime NOT NULL,
|
||||||
|
pays varchar(50) NOT NULL,
|
||||||
|
infection int(8) DEFAULT NULL,
|
||||||
|
deces int(8) DEFAULT NULL,
|
||||||
|
guerisons varchar(50) DEFAULT NULL,
|
||||||
|
tauxdeces float(10) DEFAULT NULL,
|
||||||
|
tauxguerison float(10) DEFAULT NULL,
|
||||||
|
tauxinfection float(10) DEFAULT NULL,
|
||||||
|
PRIMARY KEY (id),
|
||||||
|
UNIQUE KEY date (date,pays) USING BTREE
|
||||||
|
) ENGINE=InnoDB DEFAULT CHARSET=utf8;`
|
||||||
|
|
||||||
|
config.DbInsertPays = `
|
||||||
|
INSERT INTO coronapaysdata (date, pays, infection, deces, guerisons, tauxdeces, tauxguerison, tauxinfection)
|
||||||
|
VALUES (:date, :pays, :infection, :deces, :guerisons, :tauxdeces, :tauxguerison, :tauxinfection)
|
||||||
|
ON DUPLICATE KEY UPDATE date=:date, pays=:pays,infection=:infection, deces=:deces, guerisons=:guerisons, tauxdeces=:tauxdeces, tauxguerison=:tauxguerison, tauxinfection=:tauxinfection;`
|
||||||
|
|
||||||
|
config.DbMaxDatePays = `SELECT max(date) FROM coronapaysdata;`
|
||||||
|
|
||||||
return
|
return
|
||||||
}
|
}
|
||||||
|
|
||||||
// Config is the global config of g2g
|
// Config is the global config of g2g
|
||||||
type Config struct {
|
type Config struct {
|
||||||
DbHostname string
|
DbHostname string `ini:"db_hostname"`
|
||||||
DbName string
|
DbName string `ini:"db_name"`
|
||||||
DbUsername string
|
DbUsername string `ini:"db_username"`
|
||||||
DbPassword string
|
DbPassword string `ini:"db_password"`
|
||||||
DbTable string
|
DbTable string `ini:"db_table"`
|
||||||
DbSchemaGlobal string
|
DbSchemaGlobal string
|
||||||
DbInsertGlobal string
|
DbInsertGlobal string
|
||||||
DbSchemaPays string
|
DbMaxDateGlobal string
|
||||||
DbInsertPays string
|
DbSchemaPays string
|
||||||
Corona struct {
|
DbInsertPays string
|
||||||
URL string
|
DbMaxDatePays string
|
||||||
}
|
CoronaURL string
|
||||||
}
|
}
|
||||||
|
@ -2,11 +2,15 @@ package coronafana
|
|||||||
|
|
||||||
import (
|
import (
|
||||||
"encoding/json"
|
"encoding/json"
|
||||||
|
"fmt"
|
||||||
"io/ioutil"
|
"io/ioutil"
|
||||||
|
"log"
|
||||||
"net/http"
|
"net/http"
|
||||||
"strings"
|
"strings"
|
||||||
|
"time"
|
||||||
|
|
||||||
"git.paulbsd.com/paulbsd/coronafana/src/config"
|
"git.paulbsd.com/paulbsd/coronafana/src/config"
|
||||||
|
"github.com/jinzhu/gorm"
|
||||||
"github.com/jmoiron/sqlx"
|
"github.com/jmoiron/sqlx"
|
||||||
)
|
)
|
||||||
|
|
||||||
@ -14,7 +18,9 @@ import (
|
|||||||
func GetData(cfg config.Config) (cr Coronafana, err error) {
|
func GetData(cfg config.Config) (cr Coronafana, err error) {
|
||||||
var client http.Client
|
var client http.Client
|
||||||
|
|
||||||
resp, err := client.Get(cfg.Corona.URL)
|
log.Println("Getting JSON file ...")
|
||||||
|
|
||||||
|
resp, err := client.Get(cfg.CoronaURL)
|
||||||
if err != nil {
|
if err != nil {
|
||||||
return
|
return
|
||||||
}
|
}
|
||||||
@ -30,62 +36,122 @@ func GetData(cfg config.Config) (cr Coronafana, err error) {
|
|||||||
return
|
return
|
||||||
}
|
}
|
||||||
|
|
||||||
|
log.Println("JSON file fetched.")
|
||||||
|
|
||||||
return
|
return
|
||||||
}
|
}
|
||||||
|
|
||||||
// InsertGlobalData insert data to MySQL / MariaDB
|
// InsertGlobalData insert data to MySQL / MariaDB
|
||||||
func (cr Coronafana) InsertGlobalData(cfg config.Config, db sqlx.DB) (err error) {
|
func (cr Coronafana) InsertGlobalData(cfg config.Config, db sqlx.DB) (err error) {
|
||||||
var tx *sqlx.Tx
|
var tx *sqlx.Tx
|
||||||
|
var i int
|
||||||
|
|
||||||
|
log.Println("Start inserting global data ...")
|
||||||
tx = db.MustBegin()
|
tx = db.MustBegin()
|
||||||
txStmtglobal, err := tx.PrepareNamed(cfg.DbInsertGlobal)
|
txStmtglobal, err := tx.PrepareNamed(cfg.DbInsertGlobal)
|
||||||
for _, dt := range cr.GlobalData {
|
|
||||||
_, err = txStmtglobal.Exec(&dt)
|
|
||||||
if err != nil {
|
|
||||||
return
|
|
||||||
}
|
|
||||||
|
|
||||||
|
for _, dt := range cr.GlobalData {
|
||||||
|
if t, _ := GetParsedDate(dt.Date); t.After(cr.MaxDateGlobal) {
|
||||||
|
_, err = txStmtglobal.Exec(&dt)
|
||||||
|
if err != nil {
|
||||||
|
return
|
||||||
|
}
|
||||||
|
i++
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
err = tx.Commit()
|
err = tx.Commit()
|
||||||
if err != nil {
|
if err != nil {
|
||||||
return
|
return
|
||||||
}
|
}
|
||||||
|
|
||||||
|
if i > 0 {
|
||||||
|
log.Println(fmt.Sprintf("%d global entries to inserted", i))
|
||||||
|
} else {
|
||||||
|
log.Println("No entry inserted")
|
||||||
|
}
|
||||||
|
|
||||||
return
|
return
|
||||||
}
|
}
|
||||||
|
|
||||||
// InsertPaysData insert data to MySQL / MariaDB
|
// InsertPaysData insert data to MySQL / MariaDB
|
||||||
func (cr Coronafana) InsertPaysData(cfg config.Config, db sqlx.DB) (err error) {
|
func (cr Coronafana) InsertPaysData(cfg config.Config, db sqlx.DB) (err error) {
|
||||||
var tx *sqlx.Tx
|
var tx *sqlx.Tx
|
||||||
|
var i int
|
||||||
|
|
||||||
|
log.Println("Start inserting country data ...")
|
||||||
tx = db.MustBegin()
|
tx = db.MustBegin()
|
||||||
cr.ReplacePaysQuotes()
|
cr.ReplacePaysQuotes()
|
||||||
|
|
||||||
txStmtpays, err := tx.PrepareNamed(cfg.DbInsertPays)
|
txStmtpays, err := tx.PrepareNamed(cfg.DbInsertPays)
|
||||||
|
|
||||||
for _, dt := range cr.PaysData {
|
for _, dt := range cr.PaysData {
|
||||||
_, err = txStmtpays.Exec(&dt)
|
if t, _ := GetParsedDate(dt.Date); t.After(cr.MaxDatePays) {
|
||||||
if err != nil {
|
_, err = txStmtpays.Exec(&dt)
|
||||||
return
|
if err != nil {
|
||||||
|
return
|
||||||
|
}
|
||||||
|
i++
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
err = tx.Commit()
|
err = tx.Commit()
|
||||||
if err != nil {
|
if err != nil {
|
||||||
return
|
return
|
||||||
}
|
}
|
||||||
|
|
||||||
|
if i > 0 {
|
||||||
|
log.Println(fmt.Sprintf("%d global entries to inserted", i))
|
||||||
|
} else {
|
||||||
|
log.Println("No entry inserted")
|
||||||
|
}
|
||||||
return
|
return
|
||||||
}
|
}
|
||||||
|
|
||||||
// ReplacePaysQuotes escapes quotes in Pays names
|
// ReplacePaysQuotes escapes quotes in Pays names
|
||||||
func (cr Coronafana) ReplacePaysQuotes() (err error) {
|
func (cr *Coronafana) ReplacePaysQuotes() (err error) {
|
||||||
for _, pad := range cr.PaysData {
|
for _, pdata := range cr.PaysData {
|
||||||
pad.Pays = strings.Replace(pad.Pays, `'`, `\'`, -1)
|
pdata.Pays = strings.Replace(pdata.Pays, `'`, `\'`, -1)
|
||||||
}
|
}
|
||||||
return err
|
return
|
||||||
|
}
|
||||||
|
|
||||||
|
// GetMaxDates get max dates on table
|
||||||
|
func (cr *Coronafana) GetMaxDates(cfg config.Config, db sqlx.DB) (err error) {
|
||||||
|
var maxDateGlobal, maxDatePays string
|
||||||
|
|
||||||
|
err = db.Get(&maxDateGlobal, cfg.DbMaxDateGlobal)
|
||||||
|
if err != nil {
|
||||||
|
return
|
||||||
|
}
|
||||||
|
|
||||||
|
err = db.Get(&maxDatePays, cfg.DbMaxDatePays)
|
||||||
|
|
||||||
|
if err != nil {
|
||||||
|
return
|
||||||
|
}
|
||||||
|
|
||||||
|
cr.MaxDateGlobal, err = time.Parse("2006-01-02 15:04:05", maxDateGlobal)
|
||||||
|
cr.MaxDatePays, err = time.Parse("2006-01-02 15:04:05", maxDatePays)
|
||||||
|
|
||||||
|
return
|
||||||
|
}
|
||||||
|
|
||||||
|
// GetParsedDate returns parsed date as time.Time
|
||||||
|
func GetParsedDate(date string) (res time.Time, err error) {
|
||||||
|
res, err = time.Parse("2006-01-02T15:04:05", date)
|
||||||
|
return
|
||||||
}
|
}
|
||||||
|
|
||||||
// Coronafana is the main struct
|
// Coronafana is the main struct
|
||||||
type Coronafana struct {
|
type Coronafana struct {
|
||||||
Source string `json:"Source"`
|
gorm.Model
|
||||||
Information string `json:"Information"`
|
Source string `json:"Source"`
|
||||||
Utilisation string `json:"Utilisation"`
|
Information string `json:"Information"`
|
||||||
GlobalData []struct {
|
Utilisation string `json:"Utilisation"`
|
||||||
|
MaxDateGlobal time.Time
|
||||||
|
MaxDatePays time.Time
|
||||||
|
GlobalData []struct {
|
||||||
Date string `json:"Date" gorm:"primary_key" db:"date"`
|
Date string `json:"Date" gorm:"primary_key" db:"date"`
|
||||||
Infection int `json:"Infection" db:"infection"`
|
Infection int `json:"Infection" db:"infection"`
|
||||||
Deces int `json:"Deces" db:"deces"`
|
Deces int `json:"Deces" db:"deces"`
|
||||||
|
Loading…
Reference in New Issue
Block a user