|
|
@ -3,8 +3,6 @@ package sqlstore |
|
|
|
import ( |
|
|
|
import ( |
|
|
|
"fmt" |
|
|
|
"fmt" |
|
|
|
"math" |
|
|
|
"math" |
|
|
|
"sort" |
|
|
|
|
|
|
|
"strconv" |
|
|
|
|
|
|
|
"strings" |
|
|
|
"strings" |
|
|
|
|
|
|
|
|
|
|
|
"github.com/grafana/grafana/pkg/bus" |
|
|
|
"github.com/grafana/grafana/pkg/bus" |
|
|
@ -78,9 +76,10 @@ func DeleteExpiredVersions(cmd *m.DeleteExpiredVersionsCommand) error { |
|
|
|
affectedDashboardsQuery := fmt.Sprintf(`SELECT dashboard_id FROM dashboard_version |
|
|
|
affectedDashboardsQuery := fmt.Sprintf(`SELECT dashboard_id FROM dashboard_version |
|
|
|
GROUP BY dashboard_id HAVING COUNT(dashboard_version.id)>%d`, versionsToKeep) |
|
|
|
GROUP BY dashboard_id HAVING COUNT(dashboard_version.id)>%d`, versionsToKeep) |
|
|
|
|
|
|
|
|
|
|
|
err := x.Table("dashboard_version"). |
|
|
|
err := sess.Table("dashboard_version"). |
|
|
|
Select("dashboard_version.id, dashboard_version.version, dashboard_version.dashboard_id"). |
|
|
|
Select("dashboard_version.id, dashboard_version.version, dashboard_version.dashboard_id"). |
|
|
|
Where(fmt.Sprintf("dashboard_id IN (%s)", affectedDashboardsQuery)). |
|
|
|
Where(fmt.Sprintf("dashboard_id IN (%s)", affectedDashboardsQuery)). |
|
|
|
|
|
|
|
Desc("dashboard_version.dashboard_id", "dashboard_version.version"). |
|
|
|
Find(&versions) |
|
|
|
Find(&versions) |
|
|
|
|
|
|
|
|
|
|
|
if err != nil { |
|
|
|
if err != nil { |
|
|
@ -89,14 +88,15 @@ func DeleteExpiredVersions(cmd *m.DeleteExpiredVersionsCommand) error { |
|
|
|
|
|
|
|
|
|
|
|
// Keep last versionsToKeep versions and delete other
|
|
|
|
// Keep last versionsToKeep versions and delete other
|
|
|
|
versionIdsToDelete := getVersionIDsToDelete(versions, versionsToKeep) |
|
|
|
versionIdsToDelete := getVersionIDsToDelete(versions, versionsToKeep) |
|
|
|
versionIdsToDeleteStr := getVersionIDsToDeleteStr(versionIdsToDelete) |
|
|
|
if len(versionIdsToDelete) > 0 { |
|
|
|
deleteExpiredSql := fmt.Sprintf("DELETE FROM dashboard_version WHERE id IN (%v)", strings.Join(versionIdsToDeleteStr, ", ")) |
|
|
|
deleteExpiredSql := `DELETE FROM dashboard_version WHERE id IN (?` + strings.Repeat(",?", len(versionIdsToDelete)-1) + `)` |
|
|
|
expiredResponse, err := x.Exec(deleteExpiredSql) |
|
|
|
expiredResponse, err := sess.Exec(deleteExpiredSql, versionIdsToDelete...) |
|
|
|
if err != nil { |
|
|
|
if err != nil { |
|
|
|
return err |
|
|
|
return err |
|
|
|
} |
|
|
|
} |
|
|
|
expiredCount, _ = expiredResponse.RowsAffected() |
|
|
|
expiredCount, _ = expiredResponse.RowsAffected() |
|
|
|
} |
|
|
|
} |
|
|
|
|
|
|
|
} |
|
|
|
|
|
|
|
|
|
|
|
sqlog.Debug("Deleted old/expired dashboard versions", "expired", expiredCount) |
|
|
|
sqlog.Debug("Deleted old/expired dashboard versions", "expired", expiredCount) |
|
|
|
return nil |
|
|
|
return nil |
|
|
@ -110,48 +110,26 @@ type DashboardVersionExp struct { |
|
|
|
Version int `json:"version"` |
|
|
|
Version int `json:"version"` |
|
|
|
} |
|
|
|
} |
|
|
|
|
|
|
|
|
|
|
|
// Implement sort.Interface for []DashboardVersionExp (sort by Version field)
|
|
|
|
func getVersionIDsToDelete(versions []DashboardVersionExp, versionsToKeep int) []interface{} { |
|
|
|
type ByVersion []DashboardVersionExp |
|
|
|
versionIds := make([]interface{}, 0) |
|
|
|
|
|
|
|
|
|
|
|
func (v ByVersion) Len() int { |
|
|
|
|
|
|
|
return len(v) |
|
|
|
|
|
|
|
} |
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
func (v ByVersion) Swap(i, j int) { |
|
|
|
if len(versions) == 0 { |
|
|
|
v[i], v[j] = v[j], v[i] |
|
|
|
return versionIds |
|
|
|
} |
|
|
|
} |
|
|
|
|
|
|
|
|
|
|
|
func (v ByVersion) Less(i, j int) bool { |
|
|
|
|
|
|
|
return v[i].Version < v[j].Version |
|
|
|
|
|
|
|
} |
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
func getVersionIDsToDelete(versions []DashboardVersionExp, versionsToKeep int) []int64 { |
|
|
|
currentDashboard := versions[0].DashboardId |
|
|
|
dashboards := make(map[int64][]DashboardVersionExp) |
|
|
|
count := 0 |
|
|
|
for _, v := range versions { |
|
|
|
for _, v := range versions { |
|
|
|
elem, present := dashboards[v.DashboardId] |
|
|
|
if v.DashboardId == currentDashboard { |
|
|
|
if present { |
|
|
|
count++ |
|
|
|
dashboards[v.DashboardId] = append(elem, v) |
|
|
|
|
|
|
|
} else { |
|
|
|
} else { |
|
|
|
dashboards[v.DashboardId] = []DashboardVersionExp{v} |
|
|
|
count = 1 |
|
|
|
|
|
|
|
currentDashboard = v.DashboardId |
|
|
|
} |
|
|
|
} |
|
|
|
} |
|
|
|
if count > versionsToKeep { |
|
|
|
|
|
|
|
versionIds = append(versionIds, v.Id) |
|
|
|
versionIds := make([]int64, 0) |
|
|
|
|
|
|
|
for dashboard_id, versions := range dashboards { |
|
|
|
|
|
|
|
sort.Sort(sort.Reverse(ByVersion(versions))) |
|
|
|
|
|
|
|
dashboards[dashboard_id] = versions[versionsToKeep:] |
|
|
|
|
|
|
|
for _, ver := range dashboards[dashboard_id] { |
|
|
|
|
|
|
|
versionIds = append(versionIds, ver.Id) |
|
|
|
|
|
|
|
} |
|
|
|
} |
|
|
|
} |
|
|
|
} |
|
|
|
|
|
|
|
|
|
|
|
return versionIds |
|
|
|
return versionIds |
|
|
|
} |
|
|
|
} |
|
|
|
|
|
|
|
|
|
|
|
func getVersionIDsToDeleteStr(versionIds []int64) []string { |
|
|
|
|
|
|
|
var versionIdsToDeleteStr []string |
|
|
|
|
|
|
|
for _, versionId := range versionIds { |
|
|
|
|
|
|
|
versionIdsToDeleteStr = append(versionIdsToDeleteStr, strconv.FormatInt(versionId, 10)) |
|
|
|
|
|
|
|
} |
|
|
|
|
|
|
|
return versionIdsToDeleteStr |
|
|
|
|
|
|
|
} |
|
|
|
|
|
|
|