mirror of https://github.com/statping/statping
				
				
				
			database migrations - gh updates - 29.6
							parent
							
								
									1f2991e765
								
							
						
					
					
						commit
						5f2037a2cd
					
				| 
						 | 
				
			
			@ -18,7 +18,7 @@ services:
 | 
			
		|||
 | 
			
		||||
env:
 | 
			
		||||
  global:
 | 
			
		||||
     - VERSION=0.29.5
 | 
			
		||||
     - VERSION=0.29.6
 | 
			
		||||
     - DB_HOST=localhost
 | 
			
		||||
     - DB_USER=travis
 | 
			
		||||
     - DB_PASS=
 | 
			
		||||
| 
						 | 
				
			
			
 | 
			
		|||
| 
						 | 
				
			
			@ -1,6 +1,6 @@
 | 
			
		|||
FROM alpine:latest
 | 
			
		||||
 | 
			
		||||
ENV VERSION=v0.29.5
 | 
			
		||||
ENV VERSION=v0.29.6
 | 
			
		||||
 | 
			
		||||
RUN apk --no-cache add libstdc++ ca-certificates
 | 
			
		||||
RUN wget -q https://github.com/hunterlong/statup/releases/download/$VERSION/statup-linux-alpine.tar.gz && \
 | 
			
		||||
| 
						 | 
				
			
			
 | 
			
		|||
							
								
								
									
										120
									
								
								cli.go
								
								
								
								
							
							
						
						
									
										120
									
								
								cli.go
								
								
								
								
							| 
						 | 
				
			
			@ -1,13 +1,17 @@
 | 
			
		|||
package main
 | 
			
		||||
 | 
			
		||||
import (
 | 
			
		||||
	"encoding/json"
 | 
			
		||||
	"fmt"
 | 
			
		||||
	"github.com/hunterlong/statup/core"
 | 
			
		||||
	"github.com/hunterlong/statup/plugin"
 | 
			
		||||
	"github.com/hunterlong/statup/types"
 | 
			
		||||
	"github.com/hunterlong/statup/utils"
 | 
			
		||||
	"github.com/joho/godotenv"
 | 
			
		||||
	"io/ioutil"
 | 
			
		||||
	"math/rand"
 | 
			
		||||
	"net/http"
 | 
			
		||||
	"os"
 | 
			
		||||
	"strings"
 | 
			
		||||
	"time"
 | 
			
		||||
	"upper.io/db.v3/sqlite"
 | 
			
		||||
| 
						 | 
				
			
			@ -27,8 +31,18 @@ func CatchCLI(args []string) {
 | 
			
		|||
		core.CreateAllAssets()
 | 
			
		||||
	case "sass":
 | 
			
		||||
		core.CompileSASS()
 | 
			
		||||
	case "api":
 | 
			
		||||
		HelpEcho()
 | 
			
		||||
	case "update":
 | 
			
		||||
		gitCurrent, err := CheckGithubUpdates()
 | 
			
		||||
		if err != nil {
 | 
			
		||||
			fmt.Println(err)
 | 
			
		||||
			os.Exit(2)
 | 
			
		||||
		}
 | 
			
		||||
		fmt.Printf("Statup Version: v%v\nLatest Version: %v\n", VERSION, gitCurrent.TagName)
 | 
			
		||||
		if VERSION != gitCurrent.TagName[1:] {
 | 
			
		||||
			fmt.Printf("You don't have the latest version v%v!\nDownload the latest release at: https://github.com/hunterlong/statup\n", gitCurrent.TagName[1:])
 | 
			
		||||
		} else {
 | 
			
		||||
			fmt.Printf("You have the latest version of Statup!\n")
 | 
			
		||||
		}
 | 
			
		||||
	case "test":
 | 
			
		||||
		cmd := args[2]
 | 
			
		||||
		switch cmd {
 | 
			
		||||
| 
						 | 
				
			
			@ -52,8 +66,6 @@ func CatchCLI(args []string) {
 | 
			
		|||
		utils.Log(1, "Exported Statup index page: 'index.html'")
 | 
			
		||||
	case "help":
 | 
			
		||||
		HelpEcho()
 | 
			
		||||
	case "update":
 | 
			
		||||
		fmt.Println("Sorry updating isn't available yet!")
 | 
			
		||||
	case "run":
 | 
			
		||||
		utils.Log(1, "Running 1 time and saving to database...")
 | 
			
		||||
		RunOnce()
 | 
			
		||||
| 
						 | 
				
			
			@ -72,6 +84,10 @@ func CatchCLI(args []string) {
 | 
			
		|||
	}
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
func CheckUpdates() {
 | 
			
		||||
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
func RunOnce() {
 | 
			
		||||
	var err error
 | 
			
		||||
	core.Configs, err = core.LoadConfig()
 | 
			
		||||
| 
						 | 
				
			
			@ -265,3 +281,99 @@ func FakeSeed(plug plugin.PluginActions) {
 | 
			
		|||
	fmt.Println("Seeding example data is complete, running Plugin Tests")
 | 
			
		||||
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
func CheckGithubUpdates() (GithubResponse, error) {
 | 
			
		||||
	var gitResp GithubResponse
 | 
			
		||||
	response, err := http.Get("https://api.github.com/repos/hunterlong/statup/releases/latest")
 | 
			
		||||
	if err != nil {
 | 
			
		||||
		return GithubResponse{}, err
 | 
			
		||||
	} else {
 | 
			
		||||
		defer response.Body.Close()
 | 
			
		||||
		contents, err := ioutil.ReadAll(response.Body)
 | 
			
		||||
		if err != nil {
 | 
			
		||||
			return GithubResponse{}, err
 | 
			
		||||
		}
 | 
			
		||||
		err = json.Unmarshal(contents, &gitResp)
 | 
			
		||||
		return gitResp, err
 | 
			
		||||
	}
 | 
			
		||||
	return gitResp, err
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
type GithubResponse struct {
 | 
			
		||||
	URL             string      `json:"url"`
 | 
			
		||||
	AssetsURL       string      `json:"assets_url"`
 | 
			
		||||
	UploadURL       string      `json:"upload_url"`
 | 
			
		||||
	HTMLURL         string      `json:"html_url"`
 | 
			
		||||
	ID              int         `json:"id"`
 | 
			
		||||
	NodeID          string      `json:"node_id"`
 | 
			
		||||
	TagName         string      `json:"tag_name"`
 | 
			
		||||
	TargetCommitish string      `json:"target_commitish"`
 | 
			
		||||
	Name            string      `json:"name"`
 | 
			
		||||
	Draft           bool        `json:"draft"`
 | 
			
		||||
	Author          GitAuthor   `json:"author"`
 | 
			
		||||
	Prerelease      bool        `json:"prerelease"`
 | 
			
		||||
	CreatedAt       time.Time   `json:"created_at"`
 | 
			
		||||
	PublishedAt     time.Time   `json:"published_at"`
 | 
			
		||||
	Assets          []GitAssets `json:"assets"`
 | 
			
		||||
	TarballURL      string      `json:"tarball_url"`
 | 
			
		||||
	ZipballURL      string      `json:"zipball_url"`
 | 
			
		||||
	Body            string      `json:"body"`
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
type GitAuthor struct {
 | 
			
		||||
	Login             string `json:"login"`
 | 
			
		||||
	ID                int    `json:"id"`
 | 
			
		||||
	NodeID            string `json:"node_id"`
 | 
			
		||||
	AvatarURL         string `json:"avatar_url"`
 | 
			
		||||
	GravatarID        string `json:"gravatar_id"`
 | 
			
		||||
	URL               string `json:"url"`
 | 
			
		||||
	HTMLURL           string `json:"html_url"`
 | 
			
		||||
	FollowersURL      string `json:"followers_url"`
 | 
			
		||||
	FollowingURL      string `json:"following_url"`
 | 
			
		||||
	GistsURL          string `json:"gists_url"`
 | 
			
		||||
	StarredURL        string `json:"starred_url"`
 | 
			
		||||
	SubscriptionsURL  string `json:"subscriptions_url"`
 | 
			
		||||
	OrganizationsURL  string `json:"organizations_url"`
 | 
			
		||||
	ReposURL          string `json:"repos_url"`
 | 
			
		||||
	EventsURL         string `json:"events_url"`
 | 
			
		||||
	ReceivedEventsURL string `json:"received_events_url"`
 | 
			
		||||
	Type              string `json:"type"`
 | 
			
		||||
	SiteAdmin         bool   `json:"site_admin"`
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
type GitAssets struct {
 | 
			
		||||
	URL                string      `json:"url"`
 | 
			
		||||
	ID                 int         `json:"id"`
 | 
			
		||||
	NodeID             string      `json:"node_id"`
 | 
			
		||||
	Name               string      `json:"name"`
 | 
			
		||||
	Label              string      `json:"label"`
 | 
			
		||||
	Uploader           GitUploader `json:"uploader"`
 | 
			
		||||
	ContentType        string      `json:"content_type"`
 | 
			
		||||
	State              string      `json:"state"`
 | 
			
		||||
	Size               int         `json:"size"`
 | 
			
		||||
	DownloadCount      int         `json:"download_count"`
 | 
			
		||||
	CreatedAt          time.Time   `json:"created_at"`
 | 
			
		||||
	UpdatedAt          time.Time   `json:"updated_at"`
 | 
			
		||||
	BrowserDownloadURL string      `json:"browser_download_url"`
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
type GitUploader struct {
 | 
			
		||||
	Login             string `json:"login"`
 | 
			
		||||
	ID                int    `json:"id"`
 | 
			
		||||
	NodeID            string `json:"node_id"`
 | 
			
		||||
	AvatarURL         string `json:"avatar_url"`
 | 
			
		||||
	GravatarID        string `json:"gravatar_id"`
 | 
			
		||||
	URL               string `json:"url"`
 | 
			
		||||
	HTMLURL           string `json:"html_url"`
 | 
			
		||||
	FollowersURL      string `json:"followers_url"`
 | 
			
		||||
	FollowingURL      string `json:"following_url"`
 | 
			
		||||
	GistsURL          string `json:"gists_url"`
 | 
			
		||||
	StarredURL        string `json:"starred_url"`
 | 
			
		||||
	SubscriptionsURL  string `json:"subscriptions_url"`
 | 
			
		||||
	OrganizationsURL  string `json:"organizations_url"`
 | 
			
		||||
	ReposURL          string `json:"repos_url"`
 | 
			
		||||
	EventsURL         string `json:"events_url"`
 | 
			
		||||
	ReceivedEventsURL string `json:"received_events_url"`
 | 
			
		||||
	Type              string `json:"type"`
 | 
			
		||||
	SiteAdmin         bool   `json:"site_admin"`
 | 
			
		||||
}
 | 
			
		||||
| 
						 | 
				
			
			
 | 
			
		|||
							
								
								
									
										11
									
								
								core/core.go
								
								
								
								
							
							
						
						
									
										11
									
								
								core/core.go
								
								
								
								
							| 
						 | 
				
			
			@ -20,6 +20,8 @@ type Core struct {
 | 
			
		|||
	Footer         string     `db:"footer" json:"-"`
 | 
			
		||||
	Domain         string     `db:"domain" json:"domain,omitempty"`
 | 
			
		||||
	Version        string     `db:"version" json:"version,omitempty"`
 | 
			
		||||
	MigrationId    int64      `db:"migration_id" json:"-"`
 | 
			
		||||
	UseCdn         bool       `db:"use_cdn" json:"-"`
 | 
			
		||||
	Services       []*Service `json:"services,omitempty"`
 | 
			
		||||
	Plugins        []plugin.Info
 | 
			
		||||
	Repos          []PluginJSON
 | 
			
		||||
| 
						 | 
				
			
			@ -103,6 +105,15 @@ func (c Core) AllOnline() bool {
 | 
			
		|||
	return true
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
func SelectLastMigration() (int64, error) {
 | 
			
		||||
	var c *Core
 | 
			
		||||
	err := DbSession.Collection("core").Find().One(&c)
 | 
			
		||||
	if err != nil {
 | 
			
		||||
		return 0, err
 | 
			
		||||
	}
 | 
			
		||||
	return c.MigrationId, err
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
func SelectCore() (*Core, error) {
 | 
			
		||||
	var c *Core
 | 
			
		||||
	err := DbSession.Collection("core").Find().One(&c)
 | 
			
		||||
| 
						 | 
				
			
			
 | 
			
		|||
| 
						 | 
				
			
			@ -20,6 +20,7 @@ var (
 | 
			
		|||
	postgresSettings postgresql.ConnectionURL
 | 
			
		||||
	mysqlSettings    mysql.ConnectionURL
 | 
			
		||||
	DbSession        sqlbuilder.Database
 | 
			
		||||
	currentMigration int64
 | 
			
		||||
)
 | 
			
		||||
 | 
			
		||||
type DbConfig types.DbConfig
 | 
			
		||||
| 
						 | 
				
			
			@ -66,7 +67,10 @@ func DbConnection(dbType string) error {
 | 
			
		|||
			return err
 | 
			
		||||
		}
 | 
			
		||||
	}
 | 
			
		||||
	//dbSession.SetLogging(true)
 | 
			
		||||
	err = DbSession.Ping()
 | 
			
		||||
	if err == nil {
 | 
			
		||||
		utils.Log(1, fmt.Sprintf("Database connection to '%v' was successful.", DbSession.Name()))
 | 
			
		||||
	}
 | 
			
		||||
	return err
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
| 
						 | 
				
			
			@ -122,6 +126,7 @@ func (c *DbConfig) Save() error {
 | 
			
		|||
		ApiKey:      utils.NewSHA1Hash(9),
 | 
			
		||||
		ApiSecret:   utils.NewSHA1Hash(16),
 | 
			
		||||
		Domain:      c.Domain,
 | 
			
		||||
		MigrationId: time.Now().Unix(),
 | 
			
		||||
	}
 | 
			
		||||
	col := DbSession.Collection("core")
 | 
			
		||||
	_, err = col.Insert(newCore)
 | 
			
		||||
| 
						 | 
				
			
			@ -135,78 +140,65 @@ func (c *DbConfig) Save() error {
 | 
			
		|||
	return err
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
func versionSplit(v string) (int64, int64, int64) {
 | 
			
		||||
	currSplit := strings.Split(v, ".")
 | 
			
		||||
	if len(currSplit) < 2 {
 | 
			
		||||
		return 9999, 9999, 9999
 | 
			
		||||
	}
 | 
			
		||||
	var major, mid, minor string
 | 
			
		||||
	if len(currSplit) == 3 {
 | 
			
		||||
		major = currSplit[0]
 | 
			
		||||
		mid = currSplit[1]
 | 
			
		||||
		minor = currSplit[2]
 | 
			
		||||
		return utils.StringInt(major), utils.StringInt(mid), utils.StringInt(minor)
 | 
			
		||||
	}
 | 
			
		||||
	major = currSplit[0]
 | 
			
		||||
	mid = currSplit[1]
 | 
			
		||||
	return utils.StringInt(major), utils.StringInt(mid), 0
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
func versionHigher(migrate string) bool {
 | 
			
		||||
	cM, cMi, cMn := versionSplit(CoreApp.Version)
 | 
			
		||||
	mM, mMi, mMn := versionSplit(migrate)
 | 
			
		||||
	if mM > cM {
 | 
			
		||||
		return true
 | 
			
		||||
	}
 | 
			
		||||
	if mMi > cMi {
 | 
			
		||||
		return true
 | 
			
		||||
	}
 | 
			
		||||
	if mMn > cMn {
 | 
			
		||||
func versionHigher(migrate int64) bool {
 | 
			
		||||
	if CoreApp.MigrationId < migrate {
 | 
			
		||||
		return true
 | 
			
		||||
	}
 | 
			
		||||
	return false
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
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
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
func RunDatabaseUpgrades() error {
 | 
			
		||||
	var err error
 | 
			
		||||
	utils.Log(1, fmt.Sprintf("Checking Database Upgrades from v%v in '%v_upgrade.sql'...", CoreApp.Version, CoreApp.DbConnection))
 | 
			
		||||
	currentMigration, err = SelectLastMigration()
 | 
			
		||||
	utils.Log(1, fmt.Sprintf("Checking for Database Upgrades since #%v", currentMigration))
 | 
			
		||||
	upgrade, _ := SqlBox.String(CoreApp.DbConnection + "_upgrade.sql")
 | 
			
		||||
	// parse db version and upgrade file
 | 
			
		||||
	ups := strings.Split(upgrade, "=========================================== ")
 | 
			
		||||
	ups = reverseSlice(ups)
 | 
			
		||||
	var ran int
 | 
			
		||||
	var lastMigration int64
 | 
			
		||||
	for _, v := range ups {
 | 
			
		||||
		if len(v) == 0 {
 | 
			
		||||
			continue
 | 
			
		||||
		}
 | 
			
		||||
		vers := strings.Split(v, "\n")
 | 
			
		||||
		version := vers[0]
 | 
			
		||||
		lastMigration = utils.StringInt(vers[0])
 | 
			
		||||
		data := vers[1:]
 | 
			
		||||
 | 
			
		||||
		//fmt.Printf("Checking Migration from v%v to v%v - %v\n", CoreApp.Version, version, versionHigher(version))
 | 
			
		||||
		if !versionHigher(version) {
 | 
			
		||||
			//fmt.Printf("Already up-to-date with v%v\n", version)
 | 
			
		||||
		if currentMigration >= lastMigration {
 | 
			
		||||
			continue
 | 
			
		||||
		}
 | 
			
		||||
		fmt.Printf("Migration Database from v%v to v%v\n", CoreApp.Version, version)
 | 
			
		||||
		utils.Log(1, fmt.Sprintf("Migrating Database from #%v to #%v", currentMigration, lastMigration))
 | 
			
		||||
		for _, m := range data {
 | 
			
		||||
			if m == "" {
 | 
			
		||||
				continue
 | 
			
		||||
			}
 | 
			
		||||
			fmt.Printf("Running Migration: %v\n", m)
 | 
			
		||||
			utils.Log(1, fmt.Sprintf("Running Query: %v", m))
 | 
			
		||||
			_, err := DbSession.Exec(db.Raw(m + ";"))
 | 
			
		||||
			ran++
 | 
			
		||||
			if err != nil {
 | 
			
		||||
				utils.Log(2, err)
 | 
			
		||||
				continue
 | 
			
		||||
			}
 | 
			
		||||
			ran++
 | 
			
		||||
			CoreApp.Version = m
 | 
			
		||||
		}
 | 
			
		||||
		currentMigration = lastMigration
 | 
			
		||||
	}
 | 
			
		||||
	if ran > 0 {
 | 
			
		||||
		utils.Log(1, fmt.Sprintf("Database Upgraded, %v query ran", ran))
 | 
			
		||||
		CoreApp.Update()
 | 
			
		||||
		utils.Log(1, fmt.Sprintf("Database Upgraded %v queries ran, current #%v", ran, currentMigration))
 | 
			
		||||
		CoreApp, err = SelectCore()
 | 
			
		||||
	} else {
 | 
			
		||||
		utils.Log(1, fmt.Sprintf("Database is already up-to-date, latest v%v", CoreApp.Version))
 | 
			
		||||
		if err != nil {
 | 
			
		||||
			panic(err)
 | 
			
		||||
		}
 | 
			
		||||
		CoreApp.MigrationId = currentMigration
 | 
			
		||||
		CoreApp.Update()
 | 
			
		||||
	}
 | 
			
		||||
	return err
 | 
			
		||||
}
 | 
			
		||||
| 
						 | 
				
			
			
 | 
			
		|||
							
								
								
									
										1
									
								
								main.go
								
								
								
								
							
							
						
						
									
										1
									
								
								main.go
								
								
								
								
							| 
						 | 
				
			
			@ -65,6 +65,7 @@ func mainProcess() {
 | 
			
		|||
	if err != nil {
 | 
			
		||||
		utils.Log(3, err)
 | 
			
		||||
	}
 | 
			
		||||
 | 
			
		||||
	core.RunDatabaseUpgrades()
 | 
			
		||||
	core.InitApp()
 | 
			
		||||
 | 
			
		||||
| 
						 | 
				
			
			
 | 
			
		|||
| 
						 | 
				
			
			@ -7,7 +7,9 @@ CREATE TABLE core (
 | 
			
		|||
    style text,
 | 
			
		||||
    footer text,
 | 
			
		||||
    domain text,
 | 
			
		||||
    version VARCHAR(50)
 | 
			
		||||
    version VARCHAR(50),
 | 
			
		||||
    migration_id INT(6) NOT NULL DEFAULT 0,
 | 
			
		||||
    use_cdn BOOL NOT NULL DEFAULT '0'
 | 
			
		||||
);
 | 
			
		||||
CREATE TABLE users (
 | 
			
		||||
    id INT NOT NULL AUTO_INCREMENT PRIMARY KEY,
 | 
			
		||||
| 
						 | 
				
			
			
 | 
			
		|||
| 
						 | 
				
			
			@ -0,0 +1,4 @@
 | 
			
		|||
=========================================== 1530841150
 | 
			
		||||
ALTER TABLE core ADD COLUMN use_cdn BOOL NOT NULL DEFAULT '0';
 | 
			
		||||
=========================================== 1
 | 
			
		||||
ALTER TABLE core ADD COLUMN migration_id INT(6) NOT NULL DEFAULT 0;
 | 
			
		||||
| 
						 | 
				
			
			@ -7,7 +7,9 @@ CREATE TABLE core (
 | 
			
		|||
    style text,
 | 
			
		||||
    footer text,
 | 
			
		||||
    domain text,
 | 
			
		||||
    version text
 | 
			
		||||
    version text,
 | 
			
		||||
    migration_id integer default 0,
 | 
			
		||||
    use_cdn bool default false
 | 
			
		||||
);
 | 
			
		||||
 | 
			
		||||
CREATE TABLE users (
 | 
			
		||||
| 
						 | 
				
			
			
 | 
			
		|||
| 
						 | 
				
			
			@ -0,0 +1,4 @@
 | 
			
		|||
=========================================== 1530841150
 | 
			
		||||
ALTER TABLE core ADD COLUMN use_cdn bool DEFAULT FALSE;
 | 
			
		||||
=========================================== 1
 | 
			
		||||
ALTER TABLE core ADD COLUMN migration_id integer default 0 NOT NULL;
 | 
			
		||||
| 
						 | 
				
			
			@ -7,7 +7,9 @@ CREATE TABLE core (
 | 
			
		|||
    style text,
 | 
			
		||||
    footer text,
 | 
			
		||||
    domain text,
 | 
			
		||||
    version text
 | 
			
		||||
    version text,
 | 
			
		||||
    migration_id integer default 0,
 | 
			
		||||
    use_cdn bool default false
 | 
			
		||||
);
 | 
			
		||||
 | 
			
		||||
CREATE TABLE users (
 | 
			
		||||
| 
						 | 
				
			
			
 | 
			
		|||
| 
						 | 
				
			
			@ -0,0 +1,4 @@
 | 
			
		|||
=========================================== 1530841150
 | 
			
		||||
ALTER TABLE core ADD COLUMN use_cdn bool DEFAULT FALSE;
 | 
			
		||||
=========================================== 1
 | 
			
		||||
ALTER TABLE core ADD COLUMN migration_id integer NOT NULL DEFAULT 0;
 | 
			
		||||
		Loading…
	
		Reference in New Issue