mirror of
https://github.com/ClusterCockpit/cc-backend
synced 2024-11-10 08:57:25 +01:00
parent
60a3b653af
commit
d1e3e06b10
@ -5,7 +5,7 @@ Supports job archive version 1 and database version 4.
|
|||||||
This is the initial release of `cc-backend`, the API backend and frontend
|
This is the initial release of `cc-backend`, the API backend and frontend
|
||||||
implementation of ClusterCockpit.
|
implementation of ClusterCockpit.
|
||||||
|
|
||||||
**Breaking changes**
|
** Breaking changes **
|
||||||
|
|
||||||
The aggregate job statistic core hours is now computed using the job table
|
The aggregate job statistic core hours is now computed using the job table
|
||||||
column `num_hwthreads`. In a future release this column will be renamed to
|
column `num_hwthreads`. In a future release this column will be renamed to
|
||||||
@ -16,6 +16,16 @@ if you have exclusive jobs, only. Please be aware that we treat this column as
|
|||||||
it is the number of cores. In case you have SMT enabled and `num_hwthreads`
|
it is the number of cores. In case you have SMT enabled and `num_hwthreads`
|
||||||
is not the number of cores the core hours will be too high by a factor!
|
is not the number of cores the core hours will be too high by a factor!
|
||||||
|
|
||||||
|
** NOTE **
|
||||||
|
If you are using the sqlite3 backend the `PRAGMA` option `foreign_keys` must be
|
||||||
|
explicitly set to ON. If using the sqlite3 console it is per default set to
|
||||||
|
OFF! On every console session you must set:
|
||||||
|
```
|
||||||
|
sqlite> PRAGMA foreign_keys = ON;
|
||||||
|
|
||||||
|
```
|
||||||
|
Otherwise if you delete jobs the jobtag relation table will not be updated accordingly!
|
||||||
|
|
||||||
**Notable changes**
|
**Notable changes**
|
||||||
* Supports user roles admin, support, manager, user, and api.
|
* Supports user roles admin, support, manager, user, and api.
|
||||||
* Unified search bar supports job id, job name, project id, user name, and name
|
* Unified search bar supports job id, job name, project id, user name, and name
|
||||||
|
@ -16,7 +16,7 @@ import (
|
|||||||
"github.com/golang-migrate/migrate/v4/source/iofs"
|
"github.com/golang-migrate/migrate/v4/source/iofs"
|
||||||
)
|
)
|
||||||
|
|
||||||
const Version uint = 4
|
const Version uint = 5
|
||||||
|
|
||||||
//go:embed migrations/*
|
//go:embed migrations/*
|
||||||
var migrationFiles embed.FS
|
var migrationFiles embed.FS
|
||||||
|
@ -0,0 +1,2 @@
|
|||||||
|
ALTER TABLE tag DROP COLUMN insert_time;
|
||||||
|
ALTER TABLE jobtag DROP COLUMN insert_time;
|
@ -0,0 +1,2 @@
|
|||||||
|
ALTER TABLE tag ADD COLUMN insert_time TIMESTAMP DEFAULT CURRENT_TIMESTAMP;
|
||||||
|
ALTER TABLE jobtag ADD COLUMN insert_time TIMESTAMP DEFAULT CURRENT_TIMESTAMP;
|
@ -0,0 +1,2 @@
|
|||||||
|
ALTER TABLE tag DROP COLUMN insert_time;
|
||||||
|
ALTER TABLE jobtag DROP COLUMN insert_time;
|
18
internal/repository/migrations/sqlite3/05_extend-tags.up.sql
Normal file
18
internal/repository/migrations/sqlite3/05_extend-tags.up.sql
Normal file
@ -0,0 +1,18 @@
|
|||||||
|
ALTER TABLE tag ADD COLUMN insert_ts TEXT DEFAULT NULL /* replace me */;
|
||||||
|
ALTER TABLE jobtag ADD COLUMN insert_ts TEXT DEFAULT NULL /* replace me */;
|
||||||
|
UPDATE tag SET insert_ts = CURRENT_TIMESTAMP;
|
||||||
|
UPDATE jobtag SET insert_ts = CURRENT_TIMESTAMP;
|
||||||
|
PRAGMA writable_schema = on;
|
||||||
|
|
||||||
|
UPDATE sqlite_master
|
||||||
|
SET sql = replace(sql, 'DEFAULT NULL /* replace me */',
|
||||||
|
'DEFAULT CURRENT_TIMESTAMP')
|
||||||
|
WHERE type = 'table'
|
||||||
|
AND name = 'tag';
|
||||||
|
UPDATE sqlite_master
|
||||||
|
SET sql = replace(sql, 'DEFAULT NULL /* replace me */',
|
||||||
|
'DEFAULT CURRENT_TIMESTAMP')
|
||||||
|
WHERE type = 'table'
|
||||||
|
AND name = 'jobtag';
|
||||||
|
|
||||||
|
PRAGMA writable_schema = off;
|
@ -70,14 +70,14 @@ func (r *JobRepository) CreateTag(tagType string, tagName string) (tagId int64,
|
|||||||
|
|
||||||
func (r *JobRepository) CountTags(user *auth.User) (tags []schema.Tag, counts map[string]int, err error) {
|
func (r *JobRepository) CountTags(user *auth.User) (tags []schema.Tag, counts map[string]int, err error) {
|
||||||
tags = make([]schema.Tag, 0, 100)
|
tags = make([]schema.Tag, 0, 100)
|
||||||
xrows, err := r.DB.Queryx("SELECT * FROM tag")
|
xrows, err := r.DB.Queryx("SELECT id, tag_type, tag_name FROM tag")
|
||||||
if err != nil {
|
if err != nil {
|
||||||
return nil, nil, err
|
return nil, nil, err
|
||||||
}
|
}
|
||||||
|
|
||||||
for xrows.Next() {
|
for xrows.Next() {
|
||||||
var t schema.Tag
|
var t schema.Tag
|
||||||
if err := xrows.StructScan(&t); err != nil {
|
if err = xrows.StructScan(&t); err != nil {
|
||||||
return nil, nil, err
|
return nil, nil, err
|
||||||
}
|
}
|
||||||
tags = append(tags, t)
|
tags = append(tags, t)
|
||||||
@ -89,7 +89,7 @@ func (r *JobRepository) CountTags(user *auth.User) (tags []schema.Tag, counts ma
|
|||||||
GroupBy("t.tag_name")
|
GroupBy("t.tag_name")
|
||||||
|
|
||||||
if user != nil && user.HasAnyRole([]auth.Role{auth.RoleAdmin, auth.RoleSupport}) { // ADMIN || SUPPORT: Count all jobs
|
if user != nil && user.HasAnyRole([]auth.Role{auth.RoleAdmin, auth.RoleSupport}) { // ADMIN || SUPPORT: Count all jobs
|
||||||
log.Info("CountTags: User Admin or Support -> Count all Jobs for Tags")
|
log.Debug("CountTags: User Admin or Support -> Count all Jobs for Tags")
|
||||||
// Unchanged: Needs to be own case still, due to UserRole/NoRole compatibility handling in else case
|
// Unchanged: Needs to be own case still, due to UserRole/NoRole compatibility handling in else case
|
||||||
} else if user != nil && user.HasRole(auth.RoleManager) { // MANAGER: Count own jobs plus project's jobs
|
} else if user != nil && user.HasRole(auth.RoleManager) { // MANAGER: Count own jobs plus project's jobs
|
||||||
// Build ("project1", "project2", ...) list of variable length directly in SQL string
|
// Build ("project1", "project2", ...) list of variable length directly in SQL string
|
||||||
@ -107,7 +107,7 @@ func (r *JobRepository) CountTags(user *auth.User) (tags []schema.Tag, counts ma
|
|||||||
for rows.Next() {
|
for rows.Next() {
|
||||||
var tagName string
|
var tagName string
|
||||||
var count int
|
var count int
|
||||||
if err := rows.Scan(&tagName, &count); err != nil {
|
if err = rows.Scan(&tagName, &count); err != nil {
|
||||||
return nil, nil, err
|
return nil, nil, err
|
||||||
}
|
}
|
||||||
counts[tagName] = count
|
counts[tagName] = count
|
||||||
|
@ -124,9 +124,7 @@ type JobStatistics struct {
|
|||||||
// Tag model
|
// Tag model
|
||||||
// @Description Defines a tag using name and type.
|
// @Description Defines a tag using name and type.
|
||||||
type Tag struct {
|
type Tag struct {
|
||||||
// The unique DB identifier of a tag
|
ID int64 `json:"id" db:"id"` // The unique DB identifier of a tag
|
||||||
// The unique DB identifier of a tag
|
|
||||||
ID int64 `json:"id" db:"id"`
|
|
||||||
Type string `json:"type" db:"tag_type" example:"Debug"` // Tag Type
|
Type string `json:"type" db:"tag_type" example:"Debug"` // Tag Type
|
||||||
Name string `json:"name" db:"tag_name" example:"Testjob"` // Tag Name
|
Name string `json:"name" db:"tag_name" example:"Testjob"` // Tag Name
|
||||||
}
|
}
|
||||||
|
Loading…
Reference in New Issue
Block a user