2015-01-10 12:31:41 +00:00
|
|
|
package mysql
|
|
|
|
|
|
|
|
import (
|
|
|
|
"database/sql"
|
|
|
|
"time"
|
|
|
|
|
|
|
|
_ "github.com/go-sql-driver/mysql"
|
|
|
|
"github.com/localhots/steward/steward"
|
|
|
|
)
|
|
|
|
|
|
|
|
type (
|
|
|
|
MysqlStorage struct {
|
|
|
|
db *sql.DB
|
|
|
|
state map[string]*steward.State
|
|
|
|
|
|
|
|
importStmt *sql.Stmt
|
|
|
|
saveStateStmt *sql.Stmt
|
|
|
|
loadStateStmt *sql.Stmt
|
|
|
|
}
|
|
|
|
)
|
|
|
|
|
|
|
|
const (
|
|
|
|
importQuery = "replace into commits (sha1, author, repo, ts) values (?, ?, ?, ?)"
|
|
|
|
saveStateQuery = "replace into state (repo, sha1, ts) values (?, ?, ?)"
|
|
|
|
loadStateQuery = "select repo, sha1, ts from state"
|
|
|
|
)
|
|
|
|
|
2015-01-10 13:48:16 +00:00
|
|
|
func New(host, user, pass, db string) *MysqlStorage {
|
2015-01-10 12:31:41 +00:00
|
|
|
var (
|
|
|
|
s = &MysqlStorage{
|
|
|
|
state: map[string]*steward.State{},
|
|
|
|
}
|
2015-01-10 13:48:16 +00:00
|
|
|
err error
|
|
|
|
databaseURI = makeDatabaseURI(host, user, pass, db)
|
2015-01-10 12:31:41 +00:00
|
|
|
)
|
|
|
|
|
2015-01-10 13:48:16 +00:00
|
|
|
if s.db, err = sql.Open("mysql", databaseURI); err != nil {
|
2015-01-10 12:31:41 +00:00
|
|
|
panic(err)
|
|
|
|
}
|
|
|
|
if s.importStmt, err = s.db.Prepare(importQuery); err != nil {
|
|
|
|
panic(err)
|
|
|
|
}
|
|
|
|
if s.saveStateStmt, err = s.db.Prepare(saveStateQuery); err != nil {
|
|
|
|
panic(err)
|
|
|
|
}
|
|
|
|
|
|
|
|
s.loadGlobalState()
|
|
|
|
|
|
|
|
return s
|
|
|
|
}
|
|
|
|
|
|
|
|
func (ms *MysqlStorage) Import(repo string, hist map[string]*steward.Commit) {
|
|
|
|
var (
|
|
|
|
lastTimestamp *time.Time
|
|
|
|
lastSha1 string
|
|
|
|
)
|
|
|
|
|
|
|
|
for sha1, c := range hist {
|
|
|
|
if _, err := ms.importStmt.Exec(sha1, c.Author, repo, c.Timestamp); err != nil {
|
|
|
|
panic(err)
|
|
|
|
}
|
|
|
|
if lastTimestamp == nil || lastTimestamp.After(c.Timestamp) {
|
|
|
|
lastTimestamp = &c.Timestamp
|
|
|
|
lastSha1 = sha1
|
|
|
|
}
|
|
|
|
}
|
|
|
|
|
|
|
|
ms.saveRepoState(repo, lastSha1, *lastTimestamp)
|
|
|
|
}
|
|
|
|
|
|
|
|
func (ms *MysqlStorage) saveRepoState(repo string, sha1 string, ts time.Time) {
|
|
|
|
if _, err := ms.saveStateStmt.Exec(repo, sha1, ts); err != nil {
|
|
|
|
panic(err)
|
|
|
|
}
|
|
|
|
}
|
|
|
|
|
|
|
|
func (ms *MysqlStorage) loadGlobalState() {
|
|
|
|
var (
|
|
|
|
repo string
|
|
|
|
sha1 string
|
|
|
|
ts time.Time
|
|
|
|
)
|
|
|
|
|
|
|
|
rows, err := ms.db.Query(loadStateQuery)
|
|
|
|
if err != nil {
|
|
|
|
panic(err)
|
|
|
|
}
|
|
|
|
for rows.Next() {
|
|
|
|
if err := rows.Scan(&repo, &sha1, &ts); err != nil {
|
|
|
|
panic(err)
|
|
|
|
}
|
|
|
|
ms.state[repo] = &steward.State{
|
|
|
|
Sha1: sha1,
|
|
|
|
Timestamp: ts,
|
|
|
|
}
|
|
|
|
}
|
|
|
|
}
|
2015-01-10 13:48:16 +00:00
|
|
|
|
|
|
|
func makeDatabaseURI(host, user, pass, db string) string {
|
|
|
|
var (
|
|
|
|
databaseURI string
|
|
|
|
)
|
|
|
|
|
|
|
|
if user != "" {
|
|
|
|
databaseURI += user
|
|
|
|
}
|
|
|
|
if pass != "" {
|
|
|
|
databaseURI += ":" + pass
|
|
|
|
}
|
|
|
|
if user != "" {
|
|
|
|
databaseURI += "@"
|
|
|
|
}
|
|
|
|
if host != "" {
|
|
|
|
databaseURI += host
|
|
|
|
}
|
|
|
|
databaseURI += "/" + db + "?parseTime=true"
|
|
|
|
|
|
|
|
return databaseURI
|
|
|
|
}
|