mirror of https://github.com/statping/statping
database migrations - gh updates - 29.6
parent
1f2991e765
commit
5f2037a2cd
|
@ -18,7 +18,7 @@ services:
|
||||||
|
|
||||||
env:
|
env:
|
||||||
global:
|
global:
|
||||||
- VERSION=0.29.5
|
- VERSION=0.29.6
|
||||||
- DB_HOST=localhost
|
- DB_HOST=localhost
|
||||||
- DB_USER=travis
|
- DB_USER=travis
|
||||||
- DB_PASS=
|
- DB_PASS=
|
||||||
|
|
|
@ -1,6 +1,6 @@
|
||||||
FROM alpine:latest
|
FROM alpine:latest
|
||||||
|
|
||||||
ENV VERSION=v0.29.5
|
ENV VERSION=v0.29.6
|
||||||
|
|
||||||
RUN apk --no-cache add libstdc++ ca-certificates
|
RUN apk --no-cache add libstdc++ ca-certificates
|
||||||
RUN wget -q https://github.com/hunterlong/statup/releases/download/$VERSION/statup-linux-alpine.tar.gz && \
|
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
|
package main
|
||||||
|
|
||||||
import (
|
import (
|
||||||
|
"encoding/json"
|
||||||
"fmt"
|
"fmt"
|
||||||
"github.com/hunterlong/statup/core"
|
"github.com/hunterlong/statup/core"
|
||||||
"github.com/hunterlong/statup/plugin"
|
"github.com/hunterlong/statup/plugin"
|
||||||
"github.com/hunterlong/statup/types"
|
"github.com/hunterlong/statup/types"
|
||||||
"github.com/hunterlong/statup/utils"
|
"github.com/hunterlong/statup/utils"
|
||||||
"github.com/joho/godotenv"
|
"github.com/joho/godotenv"
|
||||||
|
"io/ioutil"
|
||||||
"math/rand"
|
"math/rand"
|
||||||
|
"net/http"
|
||||||
|
"os"
|
||||||
"strings"
|
"strings"
|
||||||
"time"
|
"time"
|
||||||
"upper.io/db.v3/sqlite"
|
"upper.io/db.v3/sqlite"
|
||||||
|
@ -27,8 +31,18 @@ func CatchCLI(args []string) {
|
||||||
core.CreateAllAssets()
|
core.CreateAllAssets()
|
||||||
case "sass":
|
case "sass":
|
||||||
core.CompileSASS()
|
core.CompileSASS()
|
||||||
case "api":
|
case "update":
|
||||||
HelpEcho()
|
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":
|
case "test":
|
||||||
cmd := args[2]
|
cmd := args[2]
|
||||||
switch cmd {
|
switch cmd {
|
||||||
|
@ -52,8 +66,6 @@ func CatchCLI(args []string) {
|
||||||
utils.Log(1, "Exported Statup index page: 'index.html'")
|
utils.Log(1, "Exported Statup index page: 'index.html'")
|
||||||
case "help":
|
case "help":
|
||||||
HelpEcho()
|
HelpEcho()
|
||||||
case "update":
|
|
||||||
fmt.Println("Sorry updating isn't available yet!")
|
|
||||||
case "run":
|
case "run":
|
||||||
utils.Log(1, "Running 1 time and saving to database...")
|
utils.Log(1, "Running 1 time and saving to database...")
|
||||||
RunOnce()
|
RunOnce()
|
||||||
|
@ -72,6 +84,10 @@ func CatchCLI(args []string) {
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
func CheckUpdates() {
|
||||||
|
|
||||||
|
}
|
||||||
|
|
||||||
func RunOnce() {
|
func RunOnce() {
|
||||||
var err error
|
var err error
|
||||||
core.Configs, err = core.LoadConfig()
|
core.Configs, err = core.LoadConfig()
|
||||||
|
@ -265,3 +281,99 @@ func FakeSeed(plug plugin.PluginActions) {
|
||||||
fmt.Println("Seeding example data is complete, running Plugin Tests")
|
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:"-"`
|
Footer string `db:"footer" json:"-"`
|
||||||
Domain string `db:"domain" json:"domain,omitempty"`
|
Domain string `db:"domain" json:"domain,omitempty"`
|
||||||
Version string `db:"version" json:"version,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"`
|
Services []*Service `json:"services,omitempty"`
|
||||||
Plugins []plugin.Info
|
Plugins []plugin.Info
|
||||||
Repos []PluginJSON
|
Repos []PluginJSON
|
||||||
|
@ -103,6 +105,15 @@ func (c Core) AllOnline() bool {
|
||||||
return true
|
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) {
|
func SelectCore() (*Core, error) {
|
||||||
var c *Core
|
var c *Core
|
||||||
err := DbSession.Collection("core").Find().One(&c)
|
err := DbSession.Collection("core").Find().One(&c)
|
||||||
|
|
|
@ -20,6 +20,7 @@ var (
|
||||||
postgresSettings postgresql.ConnectionURL
|
postgresSettings postgresql.ConnectionURL
|
||||||
mysqlSettings mysql.ConnectionURL
|
mysqlSettings mysql.ConnectionURL
|
||||||
DbSession sqlbuilder.Database
|
DbSession sqlbuilder.Database
|
||||||
|
currentMigration int64
|
||||||
)
|
)
|
||||||
|
|
||||||
type DbConfig types.DbConfig
|
type DbConfig types.DbConfig
|
||||||
|
@ -66,7 +67,10 @@ func DbConnection(dbType string) error {
|
||||||
return err
|
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
|
return err
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -122,6 +126,7 @@ func (c *DbConfig) Save() error {
|
||||||
ApiKey: utils.NewSHA1Hash(9),
|
ApiKey: utils.NewSHA1Hash(9),
|
||||||
ApiSecret: utils.NewSHA1Hash(16),
|
ApiSecret: utils.NewSHA1Hash(16),
|
||||||
Domain: c.Domain,
|
Domain: c.Domain,
|
||||||
|
MigrationId: time.Now().Unix(),
|
||||||
}
|
}
|
||||||
col := DbSession.Collection("core")
|
col := DbSession.Collection("core")
|
||||||
_, err = col.Insert(newCore)
|
_, err = col.Insert(newCore)
|
||||||
|
@ -135,78 +140,65 @@ func (c *DbConfig) Save() error {
|
||||||
return err
|
return err
|
||||||
}
|
}
|
||||||
|
|
||||||
func versionSplit(v string) (int64, int64, int64) {
|
func versionHigher(migrate int64) bool {
|
||||||
currSplit := strings.Split(v, ".")
|
if CoreApp.MigrationId < migrate {
|
||||||
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 {
|
|
||||||
return true
|
return true
|
||||||
}
|
}
|
||||||
return false
|
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 {
|
func RunDatabaseUpgrades() error {
|
||||||
var err 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")
|
upgrade, _ := SqlBox.String(CoreApp.DbConnection + "_upgrade.sql")
|
||||||
// parse db version and upgrade file
|
// parse db version and upgrade file
|
||||||
ups := strings.Split(upgrade, "=========================================== ")
|
ups := strings.Split(upgrade, "=========================================== ")
|
||||||
|
ups = reverseSlice(ups)
|
||||||
var ran int
|
var ran int
|
||||||
|
var lastMigration int64
|
||||||
for _, v := range ups {
|
for _, v := range ups {
|
||||||
if len(v) == 0 {
|
if len(v) == 0 {
|
||||||
continue
|
continue
|
||||||
}
|
}
|
||||||
vers := strings.Split(v, "\n")
|
vers := strings.Split(v, "\n")
|
||||||
version := vers[0]
|
lastMigration = utils.StringInt(vers[0])
|
||||||
data := vers[1:]
|
data := vers[1:]
|
||||||
|
|
||||||
//fmt.Printf("Checking Migration from v%v to v%v - %v\n", CoreApp.Version, version, versionHigher(version))
|
//fmt.Printf("Checking Migration from v%v to v%v - %v\n", CoreApp.Version, version, versionHigher(version))
|
||||||
if !versionHigher(version) {
|
if currentMigration >= lastMigration {
|
||||||
//fmt.Printf("Already up-to-date with v%v\n", version)
|
|
||||||
continue
|
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 {
|
for _, m := range data {
|
||||||
if m == "" {
|
if m == "" {
|
||||||
continue
|
continue
|
||||||
}
|
}
|
||||||
fmt.Printf("Running Migration: %v\n", m)
|
utils.Log(1, fmt.Sprintf("Running Query: %v", m))
|
||||||
_, err := DbSession.Exec(db.Raw(m + ";"))
|
_, err := DbSession.Exec(db.Raw(m + ";"))
|
||||||
|
ran++
|
||||||
if err != nil {
|
if err != nil {
|
||||||
utils.Log(2, err)
|
utils.Log(2, err)
|
||||||
continue
|
continue
|
||||||
}
|
}
|
||||||
ran++
|
|
||||||
CoreApp.Version = m
|
|
||||||
}
|
}
|
||||||
|
currentMigration = lastMigration
|
||||||
}
|
}
|
||||||
if ran > 0 {
|
if ran > 0 {
|
||||||
utils.Log(1, fmt.Sprintf("Database Upgraded, %v query ran", ran))
|
utils.Log(1, fmt.Sprintf("Database Upgraded %v queries ran, current #%v", ran, currentMigration))
|
||||||
CoreApp.Update()
|
|
||||||
CoreApp, err = SelectCore()
|
CoreApp, err = SelectCore()
|
||||||
} else {
|
if err != nil {
|
||||||
utils.Log(1, fmt.Sprintf("Database is already up-to-date, latest v%v", CoreApp.Version))
|
panic(err)
|
||||||
|
}
|
||||||
|
CoreApp.MigrationId = currentMigration
|
||||||
|
CoreApp.Update()
|
||||||
}
|
}
|
||||||
return err
|
return err
|
||||||
}
|
}
|
||||||
|
|
1
main.go
1
main.go
|
@ -65,6 +65,7 @@ func mainProcess() {
|
||||||
if err != nil {
|
if err != nil {
|
||||||
utils.Log(3, err)
|
utils.Log(3, err)
|
||||||
}
|
}
|
||||||
|
|
||||||
core.RunDatabaseUpgrades()
|
core.RunDatabaseUpgrades()
|
||||||
core.InitApp()
|
core.InitApp()
|
||||||
|
|
||||||
|
|
|
@ -7,7 +7,9 @@ CREATE TABLE core (
|
||||||
style text,
|
style text,
|
||||||
footer text,
|
footer text,
|
||||||
domain 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 (
|
CREATE TABLE users (
|
||||||
id INT NOT NULL AUTO_INCREMENT PRIMARY KEY,
|
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,
|
style text,
|
||||||
footer text,
|
footer text,
|
||||||
domain text,
|
domain text,
|
||||||
version text
|
version text,
|
||||||
|
migration_id integer default 0,
|
||||||
|
use_cdn bool default false
|
||||||
);
|
);
|
||||||
|
|
||||||
CREATE TABLE users (
|
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,
|
style text,
|
||||||
footer text,
|
footer text,
|
||||||
domain text,
|
domain text,
|
||||||
version text
|
version text,
|
||||||
|
migration_id integer default 0,
|
||||||
|
use_cdn bool default false
|
||||||
);
|
);
|
||||||
|
|
||||||
CREATE TABLE users (
|
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