feat: administrator (#271)

* feat: get views and failed events

* feat: get views and failed events

* feat: get views and failed events

* Update internal/view/repository/sequence.go

Co-authored-by: Livio Amstutz <livio.a@gmail.com>

* Update internal/view/repository/general_query.go

Co-authored-by: Livio Amstutz <livio.a@gmail.com>

Co-authored-by: Livio Amstutz <livio.a@gmail.com>
This commit is contained in:
Fabi
2020-06-25 08:01:13 +02:00
committed by GitHub
parent b88f200434
commit 8bfa1a083c
90 changed files with 3555 additions and 1661 deletions

View File

@@ -0,0 +1,9 @@
package model
type FailedEvent struct {
Database string
ViewName string
FailedSequence uint64
FailureCount uint64
ErrMsg string
}

View File

@@ -0,0 +1,23 @@
package model
import "github.com/caos/zitadel/internal/model"
type GeneralSearchRequest struct {
Offset uint64
Limit uint64
SortingColumn GeneralSearchKey
Asc bool
Queries []*GeneralSearchQuery
}
type GeneralSearchKey int32
const (
GeneralSearchKeyUnspecified GeneralSearchKey = iota
)
type GeneralSearchQuery struct {
Key GeneralSearchKey
Method model.SearchMethod
Value interface{}
}

View File

@@ -0,0 +1,7 @@
package model
type View struct {
Database string
ViewName string
CurrentSequence uint64
}

View File

@@ -1,4 +1,4 @@
package view
package repository
import (
"database/sql"

View File

@@ -1,4 +1,4 @@
package view
package repository
import (
"database/sql/driver"
@@ -28,6 +28,7 @@ var (
}
expectedRemoveByObject = `DELETE FROM "%s" WHERE "%s"."%s" = \$1`
expectedRemoveByObjectMultiplePK = `DELETE FROM "%s" WHERE "%s"."%s" = \$1 AND "%s"."%s" = \$2`
expectedTruncate = `TRUNCATE %s;`
expectedSearch = `SELECT \* FROM "%s" OFFSET 0`
expectedSearchCount = `SELECT count\(\*\) FROM "%s"`
expectedSearchLimit = `SELECT \* FROM "%s" LIMIT %v OFFSET 0`
@@ -289,6 +290,20 @@ func (db *dbMock) expectRemoveErr(table, key, value string, err error) *dbMock {
return db
}
func (db *dbMock) expectTruncate(table string) *dbMock {
query := fmt.Sprintf(expectedTruncate, table)
db.mock.ExpectExec(query).
WillReturnResult(sqlmock.NewResult(1, 1))
return db
}
func (db *dbMock) expectTruncateErr(table string, err error) *dbMock {
query := fmt.Sprintf(expectedTruncate, table)
db.mock.ExpectExec(query).
WillReturnError(err)
return db
}
func (db *dbMock) expectGetSearchRequestNoParams(table string, resultAmount, total int) *dbMock {
query := fmt.Sprintf(expectedSearch, table)
queryCount := fmt.Sprintf(expectedSearchCount, table)

View File

@@ -1,9 +1,11 @@
package view
package repository
import (
"github.com/caos/zitadel/internal/errors"
"github.com/caos/zitadel/internal/model"
view_model "github.com/caos/zitadel/internal/view/model"
"github.com/jinzhu/gorm"
"strings"
)
const (
@@ -57,6 +59,25 @@ func (key failedEventSearchKey) ToColumnName() string {
}
}
func FailedEventFromModel(failedEvent *view_model.FailedEvent) *FailedEvent {
return &FailedEvent{
ViewName: failedEvent.Database + "." + failedEvent.ViewName,
FailureCount: failedEvent.FailureCount,
FailedSequence: failedEvent.FailedSequence,
ErrMsg: failedEvent.ErrMsg,
}
}
func FailedEventToModel(failedEvent *FailedEvent) *view_model.FailedEvent {
dbView := strings.Split(failedEvent.ViewName, ".")
return &view_model.FailedEvent{
Database: dbView[0],
ViewName: dbView[1],
FailureCount: failedEvent.FailureCount,
FailedSequence: failedEvent.FailedSequence,
ErrMsg: failedEvent.ErrMsg,
}
}
func SaveFailedEvent(db *gorm.DB, table string, failedEvent *FailedEvent) error {
save := PrepareSave(table)
err := save(db, failedEvent)
@@ -67,6 +88,14 @@ func SaveFailedEvent(db *gorm.DB, table string, failedEvent *FailedEvent) error
return nil
}
func RemoveFailedEvent(db *gorm.DB, table string, failedEvent *FailedEvent) error {
delete := PrepareDeleteByKeys(table,
Key{Key: failedEventSearchKey(FailedEventKeyViewName), Value: failedEvent.ViewName},
Key{Key: failedEventSearchKey(FailedEventKeyFailedSequence), Value: failedEvent.FailedSequence},
)
return delete(db)
}
func LatestFailedEvent(db *gorm.DB, table, viewName string, sequence uint64) (*FailedEvent, error) {
failedEvent := new(FailedEvent)
queries := []SearchQuery{
@@ -90,3 +119,13 @@ func LatestFailedEvent(db *gorm.DB, table, viewName string, sequence uint64) (*F
return nil, errors.ThrowInternalf(err, "VIEW-9LyCB", "unable to get failed events of %s", viewName)
}
func AllFailedEvents(db *gorm.DB, table string) ([]*FailedEvent, error) {
failedEvents := make([]*FailedEvent, 0)
query := PrepareSearchQuery(table, GeneralSearchRequest{})
_, err := query(db, &failedEvents)
if err != nil {
return nil, err
}
return failedEvents, nil
}

View File

@@ -0,0 +1,53 @@
package repository
import (
global_model "github.com/caos/zitadel/internal/model"
"github.com/caos/zitadel/internal/view/model"
)
type GeneralSearchRequest model.GeneralSearchRequest
type GeneralSearchQuery model.GeneralSearchQuery
type GeneralSearchKey model.GeneralSearchKey
func (req GeneralSearchRequest) GetLimit() uint64 {
return req.Limit
}
func (req GeneralSearchRequest) GetOffset() uint64 {
return req.Offset
}
func (req GeneralSearchRequest) GetSortingColumn() ColumnKey {
if req.SortingColumn == model.GeneralSearchKeyUnspecified {
return nil
}
return GeneralSearchKey(req.SortingColumn)
}
func (req GeneralSearchRequest) GetAsc() bool {
return req.Asc
}
func (req GeneralSearchRequest) GetQueries() []SearchQuery {
result := make([]SearchQuery, len(req.Queries))
for i, q := range req.Queries {
result[i] = GeneralSearchQuery{Key: q.Key, Value: q.Value, Method: q.Method}
}
return result
}
func (req GeneralSearchQuery) GetKey() ColumnKey {
return GeneralSearchKey(req.Key)
}
func (req GeneralSearchQuery) GetMethod() global_model.SearchMethod {
return req.Method
}
func (req GeneralSearchQuery) GetValue() interface{} {
return req.Value
}
func (key GeneralSearchKey) ToColumnName() string {
return ""
}

View File

@@ -1,4 +1,4 @@
package view
package repository
import (
"fmt"

View File

@@ -1,4 +1,4 @@
package view
package repository
import (
caos_errs "github.com/caos/zitadel/internal/errors"

View File

@@ -1,4 +1,4 @@
package view
package repository
import (
"errors"
@@ -105,3 +105,15 @@ func PrepareDeleteByObject(table string, object interface{}) func(db *gorm.DB) e
return nil
}
}
func PrepareTruncate(table string) func(db *gorm.DB) error {
return func(db *gorm.DB) error {
err := db.
Exec("TRUNCATE " + table).
Error
if err != nil {
return caos_errs.ThrowInternal(err, "VIEW-lso9w", "could not truncate table")
}
return nil
}
}

View File

@@ -1,4 +1,4 @@
package view
package repository
import (
caos_errs "github.com/caos/zitadel/internal/errors"

View File

@@ -1,15 +1,17 @@
package view
package repository
import (
caos_errs "github.com/caos/zitadel/internal/errors"
"github.com/caos/zitadel/internal/view/model"
"github.com/jinzhu/gorm"
"strings"
)
type actualSequece struct {
ActualSequence uint64 `gorm:"column:current_sequence"`
}
type currentSequence struct {
type CurrentSequence struct {
ViewName string `gorm:"column:view_name;primary_key"`
CurrentSequence uint64 `gorm:"column:current_sequence"`
}
@@ -32,9 +34,18 @@ func (key sequenceSearchKey) ToColumnName() string {
}
}
func CurrentSequenceToModel(sequence *CurrentSequence) *model.View {
dbView := strings.Split(sequence.ViewName, ".")
return &model.View{
Database: dbView[0],
ViewName: dbView[1],
CurrentSequence: sequence.CurrentSequence,
}
}
func SaveCurrentSequence(db *gorm.DB, table, viewName string, sequence uint64) error {
save := PrepareSave(table)
err := save(db, &currentSequence{viewName, sequence})
err := save(db, &CurrentSequence{viewName, sequence})
if err != nil {
return caos_errs.ThrowInternal(err, "VIEW-5kOhP", "unable to updated processed sequence")
@@ -56,3 +67,22 @@ func LatestSequence(db *gorm.DB, table, viewName string) (uint64, error) {
}
return 0, caos_errs.ThrowInternalf(err, "VIEW-9LyCB", "unable to get latest sequence of %s", viewName)
}
func AllCurrentSequences(db *gorm.DB, table string) ([]*CurrentSequence, error) {
sequences := make([]*CurrentSequence, 0)
query := PrepareSearchQuery(table, GeneralSearchRequest{})
_, err := query(db, &sequences)
if err != nil {
return nil, err
}
return sequences, nil
}
func ClearView(db *gorm.DB, truncateView, sequenceTable string) error {
truncate := PrepareTruncate(truncateView)
err := truncate(db)
if err != nil {
return err
}
return SaveCurrentSequence(db, sequenceTable, truncateView, 0)
}