2018-06-30 00:57:05 +00:00
|
|
|
package core
|
|
|
|
|
|
|
|
import (
|
|
|
|
"fmt"
|
|
|
|
"github.com/go-yaml/yaml"
|
|
|
|
"github.com/hunterlong/statup/types"
|
|
|
|
"github.com/hunterlong/statup/utils"
|
|
|
|
"os"
|
|
|
|
"strings"
|
|
|
|
"time"
|
|
|
|
"upper.io/db.v3"
|
|
|
|
"upper.io/db.v3/lib/sqlbuilder"
|
|
|
|
"upper.io/db.v3/mysql"
|
|
|
|
"upper.io/db.v3/postgresql"
|
|
|
|
"upper.io/db.v3/sqlite"
|
|
|
|
)
|
|
|
|
|
|
|
|
var (
|
|
|
|
sqliteSettings sqlite.ConnectionURL
|
|
|
|
postgresSettings postgresql.ConnectionURL
|
|
|
|
mysqlSettings mysql.ConnectionURL
|
|
|
|
DbSession sqlbuilder.Database
|
2018-07-06 03:01:03 +00:00
|
|
|
currentMigration int64
|
2018-06-30 00:57:05 +00:00
|
|
|
)
|
|
|
|
|
|
|
|
type DbConfig types.DbConfig
|
|
|
|
|
|
|
|
func DbConnection(dbType string) error {
|
|
|
|
var err error
|
|
|
|
if dbType == "sqlite" {
|
|
|
|
sqliteSettings = sqlite.ConnectionURL{
|
|
|
|
Database: "statup.db",
|
|
|
|
}
|
|
|
|
DbSession, err = sqlite.Open(sqliteSettings)
|
|
|
|
if err != nil {
|
|
|
|
return err
|
|
|
|
}
|
|
|
|
} else if dbType == "mysql" {
|
|
|
|
if Configs.Port == "" {
|
|
|
|
Configs.Port = "3306"
|
|
|
|
}
|
2018-07-03 21:39:56 +00:00
|
|
|
|
2018-06-30 00:57:05 +00:00
|
|
|
mysqlSettings = mysql.ConnectionURL{
|
|
|
|
Database: Configs.Database,
|
|
|
|
Host: Configs.Host,
|
|
|
|
User: Configs.User,
|
|
|
|
Password: Configs.Password,
|
2018-07-03 21:39:56 +00:00
|
|
|
Options: map[string]string{"parseTime": "true", "charset": "utf8"},
|
2018-06-30 00:57:05 +00:00
|
|
|
}
|
|
|
|
DbSession, err = mysql.Open(mysqlSettings)
|
|
|
|
if err != nil {
|
|
|
|
return err
|
|
|
|
}
|
|
|
|
} else {
|
|
|
|
if Configs.Port == "" {
|
|
|
|
Configs.Port = "5432"
|
|
|
|
}
|
|
|
|
host := fmt.Sprintf("%v:%v", Configs.Host, Configs.Port)
|
|
|
|
postgresSettings = postgresql.ConnectionURL{
|
|
|
|
Database: Configs.Database,
|
|
|
|
Host: host,
|
|
|
|
User: Configs.User,
|
|
|
|
Password: Configs.Password,
|
|
|
|
}
|
|
|
|
DbSession, err = postgresql.Open(postgresSettings)
|
|
|
|
if err != nil {
|
|
|
|
return err
|
|
|
|
}
|
|
|
|
}
|
2018-07-06 03:01:03 +00:00
|
|
|
err = DbSession.Ping()
|
|
|
|
if err == nil {
|
|
|
|
utils.Log(1, fmt.Sprintf("Database connection to '%v' was successful.", DbSession.Name()))
|
|
|
|
}
|
2018-06-30 00:57:05 +00:00
|
|
|
return err
|
|
|
|
}
|
|
|
|
|
|
|
|
func DatabaseMaintence() {
|
|
|
|
defer DatabaseMaintence()
|
|
|
|
utils.Log(1, "Checking for database records older than 7 days...")
|
|
|
|
since := time.Now().AddDate(0, 0, -7)
|
|
|
|
DeleteAllSince("failures", since)
|
|
|
|
DeleteAllSince("hits", since)
|
|
|
|
time.Sleep(60 * time.Minute)
|
|
|
|
}
|
|
|
|
|
|
|
|
func DeleteAllSince(table string, date time.Time) {
|
|
|
|
sql := fmt.Sprintf("DELETE FROM %v WHERE created_at < '%v';", table, date.Format("2006-01-02"))
|
|
|
|
_, err := DbSession.Exec(db.Raw(sql))
|
|
|
|
if err != nil {
|
|
|
|
utils.Log(2, err)
|
|
|
|
}
|
|
|
|
}
|
|
|
|
|
|
|
|
func (c *DbConfig) Save() error {
|
|
|
|
var err error
|
|
|
|
config, err := os.Create("config.yml")
|
|
|
|
if err != nil {
|
2018-07-01 10:24:35 +00:00
|
|
|
utils.Log(4, err)
|
2018-06-30 00:57:05 +00:00
|
|
|
return err
|
|
|
|
}
|
|
|
|
data, err := yaml.Marshal(c)
|
|
|
|
if err != nil {
|
2018-07-01 10:24:35 +00:00
|
|
|
utils.Log(3, err)
|
2018-06-30 00:57:05 +00:00
|
|
|
return err
|
|
|
|
}
|
|
|
|
config.WriteString(string(data))
|
|
|
|
config.Close()
|
|
|
|
|
|
|
|
Configs, err = LoadConfig()
|
|
|
|
if err != nil {
|
2018-07-01 10:24:35 +00:00
|
|
|
utils.Log(3, err)
|
2018-06-30 00:57:05 +00:00
|
|
|
return err
|
|
|
|
}
|
|
|
|
err = DbConnection(Configs.Connection)
|
|
|
|
if err != nil {
|
2018-07-01 10:24:35 +00:00
|
|
|
utils.Log(4, err)
|
2018-06-30 00:57:05 +00:00
|
|
|
return err
|
|
|
|
}
|
|
|
|
DropDatabase()
|
|
|
|
CreateDatabase()
|
|
|
|
|
2018-06-30 03:40:00 +00:00
|
|
|
newCore := &Core{
|
2018-06-30 00:57:05 +00:00
|
|
|
Name: c.Project,
|
|
|
|
Description: c.Description,
|
|
|
|
Config: "config.yml",
|
2018-06-30 03:40:00 +00:00
|
|
|
ApiKey: utils.NewSHA1Hash(9),
|
|
|
|
ApiSecret: utils.NewSHA1Hash(16),
|
2018-06-30 00:57:05 +00:00
|
|
|
Domain: c.Domain,
|
2018-07-06 03:01:03 +00:00
|
|
|
MigrationId: time.Now().Unix(),
|
2018-06-30 00:57:05 +00:00
|
|
|
}
|
|
|
|
col := DbSession.Collection("core")
|
|
|
|
_, err = col.Insert(newCore)
|
2018-07-01 10:24:35 +00:00
|
|
|
if err == nil {
|
|
|
|
CoreApp = newCore
|
|
|
|
}
|
2018-07-04 09:00:16 +00:00
|
|
|
|
|
|
|
CoreApp, err = SelectCore()
|
|
|
|
CoreApp.DbConnection = c.DbConn
|
|
|
|
|
2018-06-30 00:57:05 +00:00
|
|
|
return err
|
|
|
|
}
|
|
|
|
|
2018-07-06 03:01:03 +00:00
|
|
|
func versionHigher(migrate int64) bool {
|
|
|
|
if CoreApp.MigrationId < migrate {
|
2018-07-04 09:00:16 +00:00
|
|
|
return true
|
|
|
|
}
|
|
|
|
return false
|
|
|
|
}
|
|
|
|
|
2018-07-06 03:01:03 +00:00
|
|
|
func reverseSlice(s []string) []string {
|
|
|
|
for i, j := 0, len(s)-1; i < j; i, j = i+1, j-1 {
|
|
|
|
s[i], s[j] = s[j], s[i]
|
|
|
|
}
|
|
|
|
return s
|
|
|
|
}
|
|
|
|
|
2018-07-04 09:00:16 +00:00
|
|
|
func RunDatabaseUpgrades() error {
|
|
|
|
var err error
|
2018-07-06 03:01:03 +00:00
|
|
|
currentMigration, err = SelectLastMigration()
|
|
|
|
utils.Log(1, fmt.Sprintf("Checking for Database Upgrades since #%v", currentMigration))
|
2018-07-04 09:00:16 +00:00
|
|
|
upgrade, _ := SqlBox.String(CoreApp.DbConnection + "_upgrade.sql")
|
|
|
|
// parse db version and upgrade file
|
|
|
|
ups := strings.Split(upgrade, "=========================================== ")
|
2018-07-06 03:01:03 +00:00
|
|
|
ups = reverseSlice(ups)
|
2018-07-04 09:00:16 +00:00
|
|
|
var ran int
|
2018-07-06 03:01:03 +00:00
|
|
|
var lastMigration int64
|
2018-07-04 09:00:16 +00:00
|
|
|
for _, v := range ups {
|
|
|
|
if len(v) == 0 {
|
|
|
|
continue
|
|
|
|
}
|
|
|
|
vers := strings.Split(v, "\n")
|
2018-07-06 03:01:03 +00:00
|
|
|
lastMigration = utils.StringInt(vers[0])
|
2018-07-04 09:00:16 +00:00
|
|
|
data := vers[1:]
|
2018-07-06 03:01:03 +00:00
|
|
|
|
2018-07-04 09:00:16 +00:00
|
|
|
//fmt.Printf("Checking Migration from v%v to v%v - %v\n", CoreApp.Version, version, versionHigher(version))
|
2018-07-06 03:01:03 +00:00
|
|
|
if currentMigration >= lastMigration {
|
2018-07-04 09:00:16 +00:00
|
|
|
continue
|
|
|
|
}
|
2018-07-06 03:01:03 +00:00
|
|
|
utils.Log(1, fmt.Sprintf("Migrating Database from #%v to #%v", currentMigration, lastMigration))
|
2018-07-04 09:00:16 +00:00
|
|
|
for _, m := range data {
|
|
|
|
if m == "" {
|
|
|
|
continue
|
|
|
|
}
|
2018-07-06 03:01:03 +00:00
|
|
|
utils.Log(1, fmt.Sprintf("Running Query: %v", m))
|
2018-07-04 09:00:16 +00:00
|
|
|
_, err := DbSession.Exec(db.Raw(m + ";"))
|
2018-07-06 03:01:03 +00:00
|
|
|
ran++
|
2018-07-04 09:00:16 +00:00
|
|
|
if err != nil {
|
|
|
|
utils.Log(2, err)
|
|
|
|
continue
|
|
|
|
}
|
2018-06-30 00:57:05 +00:00
|
|
|
}
|
2018-07-06 03:01:03 +00:00
|
|
|
currentMigration = lastMigration
|
2018-06-30 00:57:05 +00:00
|
|
|
}
|
2018-07-04 09:00:16 +00:00
|
|
|
if ran > 0 {
|
2018-07-06 03:01:03 +00:00
|
|
|
utils.Log(1, fmt.Sprintf("Database Upgraded %v queries ran, current #%v", ran, currentMigration))
|
2018-07-04 10:14:00 +00:00
|
|
|
CoreApp, err = SelectCore()
|
2018-07-06 03:01:03 +00:00
|
|
|
if err != nil {
|
|
|
|
panic(err)
|
|
|
|
}
|
|
|
|
CoreApp.MigrationId = currentMigration
|
|
|
|
CoreApp.Update()
|
2018-07-04 09:00:16 +00:00
|
|
|
}
|
|
|
|
return err
|
2018-06-30 00:57:05 +00:00
|
|
|
}
|
|
|
|
|
|
|
|
func DropDatabase() {
|
|
|
|
fmt.Println("Dropping Tables...")
|
|
|
|
down, _ := SqlBox.String("down.sql")
|
|
|
|
requests := strings.Split(down, ";")
|
|
|
|
for _, request := range requests {
|
|
|
|
_, err := DbSession.Exec(request)
|
|
|
|
if err != nil {
|
|
|
|
utils.Log(2, err)
|
|
|
|
}
|
|
|
|
}
|
|
|
|
}
|
|
|
|
|
|
|
|
func CreateDatabase() {
|
|
|
|
fmt.Println("Creating Tables...")
|
|
|
|
sql := "postgres_up.sql"
|
2018-07-04 09:00:16 +00:00
|
|
|
if CoreApp.DbConnection == "mysql" {
|
2018-06-30 00:57:05 +00:00
|
|
|
sql = "mysql_up.sql"
|
2018-07-04 09:00:16 +00:00
|
|
|
} else if CoreApp.DbConnection == "sqlite" {
|
2018-06-30 00:57:05 +00:00
|
|
|
sql = "sqlite_up.sql"
|
|
|
|
}
|
|
|
|
up, _ := SqlBox.String(sql)
|
|
|
|
requests := strings.Split(up, ";")
|
|
|
|
for _, request := range requests {
|
|
|
|
_, err := DbSession.Exec(request)
|
|
|
|
if err != nil {
|
|
|
|
utils.Log(2, err)
|
|
|
|
}
|
|
|
|
}
|
|
|
|
//secret := NewSHA1Hash()
|
|
|
|
//db.QueryRow("INSERT INTO core (secret, version) VALUES ($1, $2);", secret, VERSION).Scan()
|
|
|
|
fmt.Println("Database Created")
|
|
|
|
//SampleData()
|
|
|
|
}
|
|
|
|
|
|
|
|
func (c *DbConfig) Clean() *DbConfig {
|
|
|
|
if os.Getenv("DB_PORT") != "" {
|
|
|
|
if c.DbConn == "postgres" {
|
|
|
|
c.DbHost = c.DbHost + ":" + os.Getenv("DB_PORT")
|
|
|
|
}
|
|
|
|
}
|
|
|
|
return c
|
|
|
|
}
|